聯(lián)合索引最左匹配實測

explain各個參數(shù)的含義

  • id:表示查詢中執(zhí)行select子句或操作表的順序,如果id相同,則執(zhí)行順序從上至下,如果是子查詢,id的序號會遞增,id越大則優(yōu)先級越高,越先會被執(zhí)行。

  • select_type:有多種,常見的是simple

    • simple:表示不需要union操作或者不包含子查詢的簡單select查詢。有連接查詢時,外層的查詢?yōu)閟imple,且只有一個。
  • table:顯示的查詢表名,如果查詢使用了別名,那么這里顯示的是別名。

  • type:依次從好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index_subquery,range,index_merge,index,ALL。

  • possible_keys:查詢可能使用到的索引都會在這里列出來。

  • key:查詢真正使用到的索引

  • key_len:用于處理查詢的索引長度

  • ref:

    • 如果是使用的常數(shù)等值查詢,這里會顯示const
    • 如果是連接查詢,被驅(qū)動表的執(zhí)行計劃這里會顯示驅(qū)動表的關(guān)聯(lián)字段
    • 如果是條件使用了表達式或者函數(shù),或者條件列發(fā)生了內(nèi)部隱式轉(zhuǎn)換,這里可能顯示為func。
  • rows:這里是執(zhí)行計劃中估算的掃描行數(shù),不是精確值。

  • extra:這個列可以顯示的信息非常多,有幾十種,常用的有

    • using index:查詢時不需要回表查詢,直接通過索引就可以獲取查詢的數(shù)據(jù)。
    • using where:表示存儲引擎返回的記錄并不是所有的都滿足查詢條件,需要在server層進行過濾
  • filtered:表示存儲引擎返回的數(shù)據(jù)在server層過濾后,剩下多少滿足查詢的記錄數(shù)量的比例,注意是百分比,不是具體記錄數(shù)。

準(zhǔn)備條件

  • 版本:mysql 5.7.28

  • 共10行數(shù)據(jù),abcd4列,建立abc的聯(lián)合索引

  • a列

    • varchar 取值:甲、乙、丙、丁,其中值為甲有3個
  • b列

    • integer, 取值范圍0-100
  • c列

    • tinyInt ,取值:0、1、2
  • d列

    • varchar 取值:鉀、鈣、鈉、鎂
  • 建表語句

  CREATE TABLE `idx_abc` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `a` varchar(255) DEFAULT NULL,
    `b` int(255) DEFAULT NULL,
    `c` tinyint(255) DEFAULT NULL,
    `d` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `idx_abc` (`a`,`b`,`c`)
  ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
  • 數(shù)據(jù)截圖


    data.png

explain查詢

  • a:走a的索引
  EXPLAIN SELECT * FROM idx_abc WHERE a="甲";
1.png
  • ab:走ab的索引
  EXPLAIN SELECT * FROM idx_abc WHERE a='甲' and b=11;
2.png
  • ac:走a的索引
  EXPLAIN SELECT * FROM idx_abc WHERE a='甲' and c=2;
3.png
  • bc:全表掃描
  EXPLAIN SELECT * FROM idx_abc WHERE b=11 and c=2;
4.png
  • abc:走abc的索引
  EXPLAIN SELECT * FROM idx_abc WHERE a='甲' and b=11 and c=2;
5.png
  • ad:走a的索引
  EXPLAIN SELECT * FROM idx_abc WHERE a='甲' and d='鈉';
6.png
  • abcd:走abc的索引
  EXPLAIN SELECT * FROM idx_abc WHERE a='甲' and b=11 and c=2 and d='鈉';
7.png
  • b or c:全表掃描
EXPLAIN SELECT * FROM idx_abc WHERE b=11;
9.png

結(jié)論

  • 建立abc的聯(lián)合索引,相當(dāng)于建立了a、ab、abc三個個索引。注意是相當(dāng)于,并不是真正建立
  • 聯(lián)合索引的第一列肯定是有序的
  • 聯(lián)合索引的第二列不一定是有序的,但是在第一列值相同的第二列是有序的
  • 聯(lián)合索引的b列和c列,是沒有索引的
  • 所謂最左匹配,就是在聯(lián)合索引查詢中,where語句的條件,必須和聯(lián)合索引中的字段從左到右依次匹配(與sql語句中順序無關(guān))。如果只查詢了某幾個字段,則必須是聯(lián)合索引中,從左到右的字段,不能跳過字段。如果有跳過某個字段,就只能匹配到跳過字段左邊的,所以叫最左匹配

下一步工作

  • 聚簇索引和非聚簇索引
  • 覆蓋索引
  • mysql索引長度的意義
  • filtered的值分析
  • 索引設(shè)計優(yōu)化
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容