MySQL
索引優化order by
與group by
-
案例一
name符合最左前綴法則,但在age處斷了,所以只能用到name列,索引長度202,order by也用到了index_union索引 樹,通過Extra可看出。
-
案例二
where后符合最左前綴,所以只用到了name列,而order by處不是用的索引樹index_union,因為age還沒排序呢, position排序肯定是亂的,需要將結果集放在內存中排序。
-
案例三
如第二張圖所示,在確定最左列name后,其實下面也按age和position分別也是排好序的。
-
案例四
由案例三中的第二張圖可知,最左列name確定后,其實是按age,position排序的,但是想要position、age的方式 排序的話,需要將age,position加載到內存中再沖洗排序,通過Extra字段就可以看出來。
-
案例五
age其實已經明確是15了,一個常量值,相當於 order by position。在案例三中第二張圖就相當於明確了name是 王五,age=1的結果集,很明顯接下來的position也是排好序的。
-
案例六
在案例三中第二張圖中,age和position只能是相同順序的,才能利用到B+樹的特性,直接得出,否則還需文件排序
-
案例七
看第一個圖,很懵,即用了索引本身的排序,又用了文件排序,再看第二張圖對比下就可知,索引樹是給where用的, 而order by其實就是文件排序,如圖三,in中的這三個name雖然是排好序的,但age和position並不是已經排好序的。
-
案例八
遇到必須要用大於小於這種情況,可以使用索引覆蓋來優化他,注意Extra中的信息,using where 對應的是where條件,
using index對應的是name > 'AAA',因為select的數據都在本索引樹上,如果是*肯定不會有using index了,最后
就是order by的文件排序了。
總結
- 總計倆種排序方式:
index,filesort。using index
效率高,using filesort
效率低,using index
利用了索引樹本身的排序特性。- order by和where都需遵循最左前綴原則,類似蓋樓房的情景,沒有一樓,不可能直接蓋三樓的。
- 利用索引覆蓋減少回表
- group by本質就是先排序后分組,遵循最左前綴法則。如果分組不需要排序可以加上order by null禁止排序。
- where高於having,能卸載where中的限定條件就不要在having中限定。
單路排序:將所有需要查詢的字段放在內存中排序,而雙路只會把主鍵和需要排序的字段
放到內存中排序,最后通過主鍵id回表查詢select所需的字段。
歡迎大家訪問我的個人小站:https://www.chenmx.net