filesort
當(dāng)我們在MySQL執(zhí)行計劃中坠非,遇到了Using filesort敏沉,這就證明MySQL在執(zhí)行這條語句的時候用到了filesort,而沒有使用我們的索引進行排序炎码。所以就需要進行優(yōu)化盟迟。
具體filesort的過程如下:
1、根據(jù)表的索引或者全表掃描潦闲,讀取所有滿足條件的記錄攒菠。
2、對與每一行歉闰,存儲一對值到緩沖區(qū)(排序列辖众,行記錄指針),一個是排序的索引列的值和敬,即order by用到的列值赵辕,和指向該行數(shù)據(jù)的行指針,緩沖區(qū)的大小為sort_buffer_size大小概龄。
3、當(dāng)緩沖區(qū)滿后饲握,運行一個快速排序(qsort)來將緩沖區(qū)中數(shù)據(jù)排序私杜,并將排序完的數(shù)據(jù)存儲到一個臨時文件,并保存一個存儲塊的指針救欧,當(dāng)然如果緩沖區(qū)不滿衰粹,則不會重建臨時文件了。
4笆怠、重復(fù)以上步驟铝耻,直到將所有行讀完,并建立相應(yīng)的有序的臨時文件蹬刷。
5瓢捉、對塊級進行排序,這個類似與歸并排序算法办成,只通過兩個臨時文件的指針來不斷交換數(shù)據(jù)泡态,最終達到兩個文件,都是有序的迂卢。
6某弦、重復(fù)5直到所有的數(shù)據(jù)都排序完畢桐汤。
7、采取順序讀的方式靶壮,將每行數(shù)據(jù)讀入內(nèi)存怔毛,并取出數(shù)據(jù)傳到客戶端,這里讀取數(shù)據(jù)時并不是一行一行讀腾降,讀如緩存大小由read_rnd_buffer_size來指定拣度。
優(yōu)化使用索引排序
我們的目標(biāo)就是優(yōu)化為Using index
官網(wǎng)文檔里邊有很多優(yōu)化的方法,這里就只列舉其中講到的幾點蜂莉。
1.select字段中只包含索引字段蜡娶,避免包含無關(guān)字段。
SELECT pk, key_part1, key_part2 FROM t1
ORDER BY key_part1, key_part2;
這樣避免了filesort映穗,pk是主鍵窖张,這個也是可以通過索引查詢到了。如果使用*的話蚁滋,涉及到了回表宿接,這樣操作,還不如直接進行filesort辕录。不管怎樣睦霎,我們?nèi)粘i_發(fā)過程中,都應(yīng)該避免使用*走诞。
2.使用constant查詢聯(lián)合order by
SELECT * FROM t1
WHERE key_part1 = constant
ORDER BY key_part2;
使用了constant查詢后副女,之后對索引進行order by,這樣做后大幾率會比全表查詢效率要好蚣旱!
3.避免order by條件中一個desc 一個 asc
還有更多細節(jié)可以參考官方文檔
還有很多原則碑幅,總之最主要的就是我們的MySQL innodby引擎使用的是B+樹結(jié)構(gòu)存儲數(shù)據(jù),我們要做的就是盡可能的讓我們查詢的字段只存在于索引樹中塞绿;或者通過索引沟涨,我們能夠有效的過濾出我們需要的數(shù)據(jù)id,然后回表异吻。
https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html
https://www.cnblogs.com/aeolian/p/10212892.html