1. 程式人生 > 其它 >深入淺出談索引(下)筆記

深入淺出談索引(下)筆記

深入淺出談索引(下)筆記

由於查詢結果所需要的資料只在主鍵索引上有,所以不得不回表。可以通過一些優化的方法來避免回表的過程。

覆蓋索引

1. 什麼是覆蓋索引

在查詢時,儘量只查詢樹上包含的欄位。例如通過二級索引查詢主鍵等行為,當某些查詢頻率較高,可以嘗試建立聯合索引通過覆蓋索引的手段,提高查詢效率

2. 覆蓋索引的優點

通過覆蓋索引,可以避免回表操作減少樹的搜尋次數,顯著提升查詢效能

3. 什麼是聯合索引

  1. 聯合索引是將多個欄位,按照字典序列的b+樹,每個節點是一個多欄位的值,類似於python中的元組,例如一個聯合索引中有兩個欄位(a,b),我們只分析a的時候,會發現a是有序的;只分析b的時候是無序的,當確定a了之後,再來看b,b又是有序的。

  2. 聯合索引的失效:

    1. 最佳左字首法則

      select * from test where a=1 and b=2;
      -- 上述語句是直接命中索引的,首先找a,a是有序的,在確定了a之後找b,在a確定後b也是有序的。
      
      select * from test where b=2;
      -- 上述語句未命中索引,此時在構建的樹中,b是無序的,無法使用二分查詢。mysql找無序的資料就是全表掃描。
      
    2. 範圍查詢右邊失效的原理

      其實和上面相同,當你使用了範圍查詢,能夠鎖定部分的a值,但是去除掉了這些a之後,還有許多其他的a值繫結的b值依然是無序的。

    3. like索引失效原理

      like一般要配合百分號,一般是查字元型別的。在mysql裡字元會按照自己的演算法排好,當然也是從小到大,如字母就是用ascii碼錶排序。根據我們之前是結論,要命中索引必須要確定a的值,那麼只有a%是符合的,因為後兩種都無法確定前面的值,但是這種僅僅只有一個a%其實也是很難命中索引的,因為a開頭的值可能有一個,也可能一百萬個。

最左字首原則

B+樹結構可以利用索引的最左字首,來定位記錄。索引項是按照索引定義裡面出現的欄位順序排序的,下圖是聯合索引。

這裡注意最左字首指的是聯合索引的最左N個欄位,也可以是字串索引的最左M個字元

1.在建立聯合索引的時候,如何安排索引內的欄位順序

  1. 如何通過調整順序,可以少維護一個索引,那麼這個順序往往就是優先考慮採用的。當有了(a,b)的這個聯合索引後,一般就不需要在單獨在a上建立索引了。這個聯合索引也擁有了a單獨索引的功能。
  2. 空間原則。查詢條件裡面只有 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), 可以在索引遍歷過程中,對索引中包含的欄位先做判斷,直接過濾掉不滿足條件的記錄,減少回表次數。