深入淺出談索引(下)筆記
深入淺出談索引(下)筆記
由於查詢結果所需要的資料只在主鍵索引上有,所以不得不回表。可以通過一些優化的方法來避免回表的過程。
覆蓋索引
1. 什麼是覆蓋索引
在查詢時,儘量只查詢樹上包含的欄位。例如通過二級索引查詢主鍵等行為,當某些查詢頻率較高,可以嘗試建立聯合索引通過覆蓋索引的手段,提高查詢效率
2. 覆蓋索引的優點
通過覆蓋索引,可以避免回表操作減少樹的搜尋次數,顯著提升查詢效能
3. 什麼是聯合索引
-
聯合索引是將多個欄位,按照字典序列的b+樹,每個節點是一個多欄位的值,類似於python中的元組,例如一個聯合索引中有兩個欄位(a,b),我們只分析a的時候,會發現a是有序的;只分析b的時候是無序的,當確定a了之後,再來看b,b又是有序的。
-
聯合索引的失效:
-
最佳左字首法則
select * from test where a=1 and b=2; -- 上述語句是直接命中索引的,首先找a,a是有序的,在確定了a之後找b,在a確定後b也是有序的。 select * from test where b=2; -- 上述語句未命中索引,此時在構建的樹中,b是無序的,無法使用二分查詢。mysql找無序的資料就是全表掃描。
-
範圍查詢右邊失效的原理
其實和上面相同,當你使用了範圍查詢,能夠鎖定部分的a值,但是去除掉了這些a之後,還有許多其他的a值繫結的b值依然是無序的。
-
like索引失效原理
like一般要配合百分號,一般是查字元型別的。在mysql裡字元會按照自己的演算法排好,當然也是從小到大,如字母就是用ascii碼錶排序。根據我們之前是結論,要命中索引必須要確定a的值,那麼只有a%是符合的,因為後兩種都無法確定前面的值,但是這種僅僅只有一個a%其實也是很難命中索引的,因為a開頭的值可能有一個,也可能一百萬個。
-
最左字首原則
B+樹結構可以利用索引的最左字首,來定位記錄。索引項是按照索引定義裡面出現的欄位順序排序的,下圖是聯合索引。
這裡注意最左字首指的是聯合索引的最左N個欄位,也可以是字串索引的最左M個字元
1.在建立聯合索引的時候,如何安排索引內的欄位順序
- 如何通過調整順序,可以少維護一個索引,那麼這個順序往往就是優先考慮採用的。當有了(a,b)的這個聯合索引後,一般就不需要在單獨在a上建立索引了。這個聯合索引也擁有了a單獨索引的功能。
- 空間原則。查詢條件裡面只有 b 的語句,是無法使用 (a,b) 這個聯合索引的,這時候你不得不維護另外一個索引,也就是說你需要同時維護 (a,b)、(b) 這兩個索引。比如name 欄位是比 age 欄位大的 ,建立一個(name,age) 的聯合索引和一個 (age) 的單欄位索引。
索引下推
select * from tuser where name like '張%' and age=10 and ismale=1
在 MySQL 5.6 之前,只能通過最左字首找到對應的主鍵後,開始一個個回表。到主鍵索引上找出資料行,再對比欄位值。
而 MySQL 5.6 引入的索引下推優化(index condition pushdown), 可以在索引遍歷過程中,對索引中包含的欄位先做判斷,直接過濾掉不滿足條件的記錄,減少回表次數。