在某些情況下,MySQL數據庫能夠直接利用索引來中意一個ORDER BY或GROUP BY子句而無需做額外的排序。盡管ORDER BY不是和索引的次序准確相稱,索引還是能夠被用到,因為凡是無須的索引局部和所有的額外的ORDER BY字段在WHERE子句中都被包括了。 本文我們主要介紹MySQL數據庫中的索引和Order By子句的使用問題,接下來我們開始介紹。
利用索引的MySQL Order By
下列的幾個查詢都會利用索引來處理 ORDER BY 或 GROUP BY 局部:
- SELECT * FROM t1 ORDER BY key_part1,key_part2,... ;
- SELECT * FROM t1 WHERE key_part1=constant ORDER BY key_part2;
- SELECT * FROM t1 WHERE key_part1=constant GROUP BY key_part2;
- SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC;
- SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC, key_part2 DESC;
不利用索引的MySQL Order By
在另一些情形下,MySQL無法利用索引來中意 ORDER BY,盡管它會利用索引來找到登記來相稱 WHERE 子句。這些情形如下:
對不同的索引鍵做ORDER BY : SELECT * FROM t1 ORDER BY key1, key2;
在非繼續的索引鍵局部上做 ORDER BY: SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2;
同時利用了 ASC 和 DESC: SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
用於搜查登記的索引鍵和做 ORDER BY 的不是統一個: SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
有許多表同時做連接,而且讀取的登記中在 ORDER BY 中的字段都不全是來自第一個極其數的表中也即便說,在 EXPLAIN 分析的收獲中的第一個表的連接種類不是 const)。
利用了不同的ORDER BY和GROUP BY表白式。
表索引中的登記不是按序存儲。例如,HASH 和 HEAP 表即便這麼。穿越厲行 EXPLAIN SELECT ... ORDER BY,就懂得MySQL是否在查詢中利用了索引。萬一 Extra 字段的值是 Using filesort,則解釋MySQL無法利用索引。
當定然對收獲舉行排序時,MySQL 4.1過去它利用了以下 filesort 算法:
1. 依據索引鍵讀取登記,可能掃描數據表。那些無法相稱 WHERE 分句的登記都會被略過。
2. 在緩沖中每條登記都用一個‘對’存儲了2個值索引鍵及登記指針)。緩沖的大小依據系統變量 sort_buffer_size 的值而定。
3. 當緩沖慢了時,就運行 qsort迅速排序)並將收獲存儲在臨時文件中。將存儲的塊指針保留起來萬一所有的‘對’值都能保留在緩沖中,就無需創立臨時文件了)。
4. 厲行上面的壟斷,直到所有的登記都讀取出來了。
5. 做順次多重並合,將多達 MERGEBUFF7)個區域的塊保留在另一個臨時文件中。重復這個壟斷,直到所有在第一個文件的塊都放到第二個文件了。
6. 重復以上壟斷,直到富余的塊數量小於 MERGEBUFF2 (15)。
7. 在最後順次多重並合時,只有登記的指針排序索引鍵的最後局部)寫到收獲文件中去。
8. 穿越讀取收獲文件中的登記指針來按序讀取登記。想要優化這個壟斷,MySQL將登記指針讀取放到一個大的塊裡,並且利用它來按序讀取登記,將登記放到緩沖中。緩沖的大小由系統變量 read_rnd_buffer_size 的值而定。這個環節的代碼在源文件 `sqlgexinghua.org/費雪records.cc' 中。這個接近算法的一個問題是,數據庫讀取了2次登記:順次是估價 WHERE 分句時,第二次是排序時。盡管第順次都獲勝讀取登記了例如,做了順次全表掃描),第二次是隨機的讀取索引鍵曾經排好序了,然而登記並未曾)。
在MySQL 4.1 及更新版本中,filesort 優化算法用於登記中不但包括索引鍵值和登記的位置,還包括查詢中要求的字段。這麼做避免了必需2次讀取登記。改進的 filesort 算法做法大約如下:
1. 跟隨前一樣,讀取相稱 WHERE 分句的登記。
2. 相對於每個登記,都登記了一個對應的;‘元組’消息消息,包括索引鍵值、登記位置、以及查詢中所必需的所有字段。
3. 依據索引鍵對‘元組’消息舉行排序。
4. 按序讀取登記,不過是從曾經排序過的‘元組’列表中讀取登記,而非從數據表中再讀取順次。 利用改進後的 filesort 算法相比本來的,‘元組’比‘對’必需挪借更長的空間,它們很少剛好合乎放在排序緩沖中緩沖的大小是由 sort_buffer_size 的值定奪的)。因而,這就可能必需有更多的I/O壟斷,導致改進的算法更慢。為了避免使之變慢,這種優化措施只用於排序‘元組’中額外的字段的大小總和超過系統變量 max_length_for_sort_data 的情形這個變量的值設置太高的一個假象即便高磁盤負載低CPU負載)。
想要長進ORDER BY 的速度,率先要看MySQL能否利用索引而非額外的排序過程。萬一不能利用索引,能夠試著順從以下計策:
添置sort_buffer_size 的值。
添置read_rnd_buffer_size 的值。
修正tmpdir,讓它指向一個有許多富余空間的專用文件系統。
關於MySQL數據庫Order By索引優化方面的知識就介紹到這裡了,如果您想了解更多關於MySQL數據庫的知識,可以看一下這裡的文章:http://database.51cto.com/mysql/,相信一定能夠帶給您收獲的!