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)化
