昨天同事關於軍規裡的一條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無法排序。
解釋:order by的排序原理
1.利用索引的有序性獲取有序資料
2.利用記憶體/磁碟檔案排序獲取結果
1) 雙路排序:是首先根據相應的條件取出相應的排序欄位和可以直接定位行資料的行指標資訊,然後在sort buffer 中進行排序。
2)單路排序:是一次性取出滿足條件行的所有字段,然後在sort buffer中進行排序。
組合索引的有序性和最左字首原理
【強制】理解組合索引最左字首原則,避免重複建設索引,如果建立了(a,b,c),相當於建立了(a), (a,b), (a,b,c)
假設有索引(a,b)
mysql建立組合索引的規則是首先會對復合索引的最左邊的,也就是第乙個a欄位的資料進行排序,在第乙個欄位的排序基礎上,然後再對後面第二個的b欄位進行排序。其實就相當於實現了類似 order by a b這樣一種排序規則。
第乙個a欄位是絕對有序的,而第二字段就是無序的了。所以通常情況下,直接使用第二個b欄位進行條件判斷是用不到索引的
那麼什麼時候才能用到呢?
當然是b欄位的索引資料也是有序的情況下才能使用。
什麼時候才是有序的呢?
只有在a欄位是等值匹配的情況下,b才是有序的。
組合索引查詢的各種場景
有 index (a,b,c) ——組合索引多字段是有序的,並且是個完整的btree 索引。
下面條件可以用上該組合索引查詢:
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的執行過程
**:
mysql索引 有序性 mysql組合索引的有序性
昨天同事關於軍規裡的一條mysql索引的問題諮詢我,才發現自己也不太了解組合索引的規則。於是來記錄一下 推薦 如果有order by的場景,請注意利用索引的有序性。order by 最後的字段是組合索引的一部分,並且放在索引組合順序的最後,避免出現file sort的情況,影響查詢效能。正例 whe...
關於原子性, 可見性,有序性的思考
原子性是指 不會有中間狀態存在,要麼什麼都沒改變,要麼全都改變 對資料操作的原子性 在併發程式設計中,原子性存在的根本原因是,多個執行緒操作共享變數,由於執行緒間切換排程,導致乙個執行緒操作了另乙個執行緒 半成品 的資料,這是導致多執行緒環境下結果不可 的乙個原因.synchronized 的原子性...
訊息佇列如何確保訊息的有序性?
要想實現訊息有序,需要從 producer 和 consumer 兩方面來考慮。首先,producer 生產訊息的時候就必須要有序。然後,consumer 消費的時候,也要按順序來,不能亂。producer 有序 像 rabbitmq 這類普通的訊息系統,佇列結構簡單,producer 向佇列中傳送...