Mysql-索引失效 order by優化

Mysql-索引失效 order by優化

索引失效

  • 最佳左前綴法則

    如果索引了多列 要遵循最佳左前綴法則 指從查詢索引的最左前列開始並且不跳過索引中的列

    在這裏插入圖片描述

    在這裏插入圖片描述

  • 不在索引列上做任何操作 會導致索引失效而轉向全表掃描

    在這裏插入圖片描述

  • 不能使用索引中範圍條件右邊的列

    在這裏插入圖片描述

  • 儘量使用覆蓋索引

    在這裏插入圖片描述

  • 在使用不等於(!=或者<>)的時候 無法使用索引會導致全表掃描

    在這裏插入圖片描述

  • is null 和is not null也無法使用索引

    在這裏插入圖片描述

  • lile以通配符開頭 會造成索引失效變成全表掃描

    百分號開頭的情況下 會造成索引失效

    如果必須得用百分開頭 如%abc% 這種情況 則可以利用覆蓋索引解決索引失效的問題

  • 字符串不加單引號 會導致索引失效

    在這裏插入圖片描述

  • 小結

    在這裏插入圖片描述

  • 練習1

    在這裏插入圖片描述

  • 練習2

    在這裏插入圖片描述

    只用c1 一個字段索引 但是c2 c3 用於排序

  • 練習3

    在這裏插入圖片描述

    第二個sql c1 c2 用於索引 c2 和 c3 用於排序

  • 練習4

    在這裏插入圖片描述

order by關鍵字優化

  • 上手案例

    在這裏插入圖片描述

  • 1.where條件限制,order by 2 字段(2字段爲已建立組合索引字段,並按照組合索引的順序排序),索引生效

在這裏插入圖片描述

  • 2.where條件限制,order by 2 字段(2字段爲已建立組合索引字段,但排序的順序和組合索引的順序不一致),出現Using filesort

    EXPLAIN SELECT * FROM emp WHERE age = 45 ORDER BY name ,deptId;
    

在這裏插入圖片描述

  • 3.where條件限制,order by 2 字段(其中某一字段爲非組合索引字段),出現Using filesort

    EXPLAIN SELECT * FROM emp WHERE age = 45 ORDER BY deptId ,empno;
    

在這裏插入圖片描述

  • 4.where條件限制,where and條件的值確定,排序條件中有該定值字段,即使order by後字段順序和組合索引的順序不一致(排序字段去除定值字段後剩餘字段後組合索引順序一致),此時不會出現Using filesort

    EXPLAIN SELECT * FROM emp WHERE age = 45 ORDER BY deptId,age;
    

在這裏插入圖片描述

  • 5.order by後跟的排序字段是desc和asc 組合,不論排序順序是否和組合索引順序一致,必然會出現Using filesort

    EXPLAIN SELECT * FROM emp WHERE age = 45 ORDER BY deptId DESC,name ASC;
    

在這裏插入圖片描述

  • order by索引對比

    1)無過濾條件(無where和limit)的order by 必然會出現 Using filesort
    2)過濾條件中的字段和order by 後跟的字段的順序不一致,必然會出現 Using filesort
    3)order by後跟的字段排序即有DESC也有ASC,必然會出現Using filesort
    4)where條件的值確定,且order by後跟了跟了where條件的排序字段(order by 字段去除定值字段後剩餘單字段),即使order by後跟的字段和組合索引字段順序不一致,也不會出現Usi

  • order by索引建議

    1)儘量在索引列上完成排序操作,遵循最佳做前綴法則
    2)order by子句,儘量使用index方式排序,避免使用filesort方式

  • 無索引 order by的索引建議

    雙路排序:掃描2次磁盤獲取最終數據,第一次掃描讀取行指針和order by字段列的值進行排序,刷選出需要的排完序的行指針,第二次掃描讀取所需的全部數據
    單路排序:從磁盤中讀取查詢所需的全部列,在buff中進行排序,排序後進行輸出,只需要掃描一次磁盤
    問題:雙路排序相比單路排序會減少I/O次數,但會消耗更多的內存,如果取出的數據總大小超出sort_buffer的容量,會創建temp文件進行多路合併,反而會增加I/O次數,同理雙路排序也會出現同樣的問題,但單路排序的相對機率要高很多
    優化:
    1)增大sort_buffer_size
    2)增大max_length_for_sort_data
    3)減少select後跟的查詢字段

  • 小結

    key a b c(a,b,c)
    
    order by能使用索引最左前綴
    - order by a
    - order by a,b
    - order by a,b,c
    - order by a DESC,b DESC,c DESC
    
    如果where使用了索引的最左前綴定義爲常量  則order by能使用索引
    - WHERE a=const order by b,c
    - WHERE a=const AND b=const ORDRE BY c
    - WHERE a=const AND b>const ORDER BY b,c
    
    不能使用索引進行排序
    - ORDERE BY a ASC,b DESC,c DESC   排序不一致
    - WHERE g=const ORDER BY b,c   丟失a索引
    - WHERE a=const ORDER BY C  丟失b索引
    - WHERE a=const ORDER BY d  d不是索引的一部分
    
    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章