MySQL索引優化order by與group by


MySQL索引優化order bygroup by

  • 案例一
    image-20210821184738861

    name符合最左前綴法則,但在age處斷了,所以只能用到name列,索引長度202,order by也用到了index_union索引
    樹,通過Extra可看出。
    
  • 案例二
    image-20210821185046629

    where后符合最左前綴,所以只用到了name列,而order by處不是用的索引樹index_union,因為age還沒排序呢,
    position排序肯定是亂的,需要將結果集放在內存中排序。
    
  • 案例三
    image-20210821195324399
    image-20210821195503461

    如第二張圖所示,在確定最左列name后,其實下面也按age和position分別也是排好序的。
    
  • 案例四
    image-20210821195758759

    由案例三中的第二張圖可知,最左列name確定后,其實是按age,position排序的,但是想要position、age的方式
    排序的話,需要將age,position加載到內存中再沖洗排序,通過Extra字段就可以看出來。
    
  • 案例五
    image-20210821200353902

    age其實已經明確是15了,一個常量值,相當於 order by position。在案例三中第二張圖就相當於明確了name是
    王五,age=1的結果集,很明顯接下來的position也是排好序的。
    
  • 案例六
    image-20210821200731981

    在案例三中第二張圖中,age和position只能是相同順序的,才能利用到B+樹的特性,直接得出,否則還需文件排序
    
  • 案例七
    image-20210821201702926
    image-20210821201736270
    image-20210821202056043

    看第一個圖,很懵,即用了索引本身的排序,又用了文件排序,再看第二張圖對比下就可知,索引樹是給where用的,
    而order by其實就是文件排序,如圖三,in中的這三個name雖然是排好序的,但age和position並不是已經排好序的。
    
  • 案例八

    image-20210821202455316

    image-20210821202755758

遇到必須要用大於小於這種情況,可以使用索引覆蓋來優化他,注意Extra中的信息,using where 對應的是where條件,
using index對應的是name > 'AAA',因為select的數據都在本索引樹上,如果是*肯定不會有using index了,最后
就是order by的文件排序了。

總結

  1. 總計倆種排序方式:index,filesort。using index效率高,using filesort效率低,using index利用了索引樹本身的排序特性。
  2. order by和where都需遵循最左前綴原則,類似蓋樓房的情景,沒有一樓,不可能直接蓋三樓的。
  3. 利用索引覆蓋減少回表
  4. group by本質就是先排序后分組,遵循最左前綴法則。如果分組不需要排序可以加上order by null禁止排序。
  5. where高於having,能卸載where中的限定條件就不要在having中限定。

image-20210821204046334

單路排序:將所有需要查詢的字段放在內存中排序,而雙路只會把主鍵和需要排序的字段
放到內存中排序,最后通過主鍵id回表查詢select所需的字段。

歡迎大家訪問我的個人小站https://www.chenmx.net


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM