保證給你講明白,看不懂你砍我。
首先弄明白兩個概念-大概說一下,具體的網上都有:
覆蓋索引-select b,c,d from t1
;
select b,c,d from t1 where b=1 and c =1 and d=1
;
select a,b,c,d from t1 where b=1 and c =1 and d=1
;
【a是主鍵,給bcd建立聯合索引】,如上幾個sql,select出來的內容,和where條件字段,剛好和建立的索引一致.
回表-使用非聚簇索引進行查找數據時,需要根據主鍵值去聚簇索引中再查找一遍完整的用戶記錄,這個過程叫做回表.
上面兩個概念清楚以后,繼續往下看。
新建一張測試表 t1.如下。
備注:a列設置為主鍵列,bcd列建立聯合索引,其他列暫時沒有建立索引。
a | b | c | d | e |
---|---|---|---|---|
1 | 15 | 16 | 17 | x |
2 | 25 | 26 | 27 | x |
3 | 35 | 36 | 37 | x |
4 | 45 | 46 | 47 | x |
5 | 55 | 56 | 57 | x |
6 | 65 | 66 | 67 | x |
7 | 75 | 76 | 77 | x |
8 | 85 | 86 | 87 | x |
執行sql,如下:
select b,c,d from t1 where b=15 and c=16 and d=17
這里使用了 覆蓋索引。我們看下他的B+樹。
分析上圖,滿足條件的結果,是不是完整的顯示在了葉子節點上???【注意:我們select查詢的內容不是全表,是bcd三個字段,在葉子節點上,這3個字段是不是都已經有對應的值了。】
即使我們sql寫這樣子:
select a,b,c,d from t1 where b=15 and c=16 and d=17
a是主鍵列,但是在聯合索引的葉子節點上,頁存儲了對應的主鍵值,所以依舊不需要回表操作。
總結:使用覆蓋索引,我們需要select出來的列,都已經存在了索引樹的葉子節點上。所以不需要回表操作,如果我們select出來的某列,不在該聯合索引的葉子節點上(比如上表的e列),那就需要根據對應索引值,去聚簇索引樹上回表查詢對應的e列值了。