聯合索引有哪些講究?

1. 認識聯合索引

聯合索引:是指對錶上的多個列進行索引。適合where條件中的多列組合,在某些場景可以避免回表。
如下圖所示:
在這裏插入圖片描述
在進行order by操作時,聯合索引的字段數量大於1,比如上圖就有a和b兩個字段,與單個字段的B+樹一樣,也是按照字段排序的。比如圖中a、b兩個字段的值都是(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),是按照(a,b)進行排序的。因此對於a、b兩個字段都作爲條件時,查詢是可以走索引的;對於單獨a字段查詢也是可以走索引的。但是對於b字段單獨查詢就走不了索引了,因爲b字段對應的值是1,2,3,1,2,3,顯然不是有序的,所以走不了b字段的索引。
所以當使用聯合索引的時候:

  • 在where條件中,經常同時出現的列放在聯合索引中;
  • 把選擇性最大的列放在聯合索引的最左邊;

2. 聯合索引使用分析

2.1 可以完整用到聯合索引的情況

  • a、b、c爲一個聯合索引,因此當聯合索引各字段都作爲條件時
select * from t11 where a=1 and b=1 and c=1;
  • 各字段的位置不會影響聯合索引的使用
select * from t11 where c=1 and b=1 and a=1;
  • 當聯合索引前面的字段使用了範圍查詢,後面的字段作爲條件時仍然可以使用完整的聯合索引
select * from t11 where a=2 and b in (1,2) and c=2;
  • 聯合索引前面的字段作爲條件時,對後面的字段做排序可以使用完整的聯合索引
select * from t11 where a=1 and b=2 order by c;
  • 對聯合索引第一個字段做條件篩選時,對後面兩個字段做排序可以使用完整的聯合索引
select * from t11 where a=1 order by b,c;
  • 對聯合索引的字段同時做排序時,排序的是三個字段要跟聯合索引中的三個字段完全一致,而且查詢出的字段只能是聯合索引中的字段,可以完整的用到聯合索引

2.2 只能使用部分聯合索引的情況

  • 當條件只包含聯合索引的前面部分字段時,可以用到部分聯合索引
select * from t11 where a=1 and b=1;
  • 對於聯合索引a,b,c,如果條件中只包含a和c,則只能用到聯合索引中a的索引。c這裏是用不了索引的。聯合索引a、b、c相當於單個索引a、聯合索引a、b,聯合索引a、b、c三種索引,稱爲聯合索引的最左原則。
select * from t11 where a=1 and c=1; 
  • 當聯合索引前面的字段使用了範圍查詢,對後面的字段排序使用不了索引排序,也就是說只能用到聯合索引的前面兩個字段a和b的索引

2.3 可以用到覆蓋索引的情況

覆蓋索引就是從輔助索引中就可以查詢到結果,不需要回表查詢聚集索引中的記錄。通過覆蓋索引,不需要回表掃描聚集索引,因此可以減少SQL執行過程中的IO次數。

  • 通過a字段上的條件,去聯合索引idx_a_b_c的索引樹上可以直接找到b字段和c字段的值,不需要回表,因此下面的SQL語句使用了覆蓋索引

    select b,c from t11 where a=3; 
    
  • 通過a和b字段的值可以字節找到c的值,因此下面SQL語句使用了覆蓋索引

    select c from t11 where a=1 and b=1 ;
    
  • 通過a、b、c三個字段的值,去聯合索引樹中的葉子節點找到主鍵id,不需要回表,因此下面SQL語句使用了覆蓋索引

    select id from t11 where a=1 and b=1 and c=1;
    

2.4 不能使用聯合索引的情況

  • 如果只使用聯合索引後面的字段作爲條件查詢,則使用不了聯合索引,因爲聯合索引的最左匹配原則,如果第一個字段在條件中沒有出現,那麼聯合索引的後面所有字段作爲條件都無法使用這個聯合索引

    select * from t11 where b=1;
    
  • 對聯合索引後面的字段做排序操作,也使用不了聯合索引

    select * from t11 where c=1;
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章