昨天同事關於軍規裏的一條mysql索引的問題諮詢我,才發現本身也不太瞭解組合索引的規則。因而來記錄一下:mysql
【推薦】若是有order by的場景,請注意利用索引的有序性。order by 最後的字段是組合索引的一部分,而且放在索引組合順序的最後,避免出現file_sort的狀況,影響查詢性能。
正例:where a=? and b=? order by c; 索引:a_b_c
反例:索引中有範圍查找,那麼索引有序性沒法利用,如:WHERE a>10 ORDER BY b; 索引a_b沒法排序。sql
解釋:order by的排序原理
1.利用索引的有序性獲取有序數據
2.利用內存/磁盤文件排序獲取結果
1) 雙路排序:是首先根據相應的條件取出相應的排序字段和能夠直接定位行數據的行指針信息,而後在sort buffer 中進行排序。
2)單路排序:是一次性取出知足條件行的全部字段,而後在sort buffer中進行排序。性能
組合索引的有序性和最左前綴原理
【強制】理解組合索引最左前綴原則,避免重複建設索引,若是創建了(a,b,c),至關於創建了(a), (a,b), (a,b,c)mysql索引
假設有索引(A,B)
mysql建立組合索引的規則是首先會對複合索引的最左邊的,也就是第一個A字段的數據進行排序,在第一個字段的排序基礎上,而後再對後面第二個的B字段進行排序。其實就至關於實現了相似 order by A B這樣一種排序規則。
第一個A字段是絕對有序的,而第二字段就是無序的了。因此一般狀況下,直接使用第二個B字段進行條件判斷是用不到索引的
那麼何時才能用到呢?
固然是B字段的索引數據也是有序的狀況下才能使用。
何時纔是有序的呢?
只有在A字段是等值匹配的狀況下,B纔是有序的。.net
組合索引查詢的各類場景
有 Index (A,B,C) ——組合索引多字段是有序的,而且是個完整的BTree 索引。 指針
下面條件能夠用上該組合索引查詢: blog
A>5 排序
A=5 AND B>6 索引
A=5 AND B=6 AND C=7 內存
A=5 AND B IN (2,3) AND C>5
下面條件將不能用上組合索引查詢:
B>5 ——查詢條件不包含組合索引首列字段
B=6 AND C=7 ——查詢條件不包含組合索引首列字段
下面條件將能用上部分組合索引查詢:
A>5 AND B=2 ——當範圍查詢使用第一列,查詢條件僅僅能使用第一列
A=5 AND B>6 AND C=2 ——範圍查詢使用第二列,查詢條件僅僅能使用前二列
組合索引排序的各類場景
有組合索引 Index(A,B)。
下面條件能夠用上組合索引排序:
ORDER BY A——首列排序
A=5 ORDER BY B——第一列過濾後第二列排序
ORDER BY A DESC, B DESC——注意,此時兩列以相同順序排序
A>5 ORDER BY A——數據檢索和排序都在第一列
下面條件不能用上組合索引排序:
ORDER BY B ——排序在索引的第二列
A>5 ORDER BY B ——範圍查詢在第一列,排序在第二列
A IN(1,2) ORDER BY B ——理由同上
ORDER BY A ASC, B DESC ——注意,此時兩列以不一樣順序排序
建議
若是對有沒有用上索引有疑惑能夠寫完sql之後 用explain 來運行一下sql
能夠更有利於理解sql的執行過程