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






