explain能干啥
mysql官方介紹:
When EXPLAIN is used with an explainable statement, MySQL displays information from the optimizer about the statement execution plan. That is, MySQL explains how it would process the statement, including information about how tables are joined and in which order.
explain能解釋mysql如何處理SQL語句,表的加載順序,表是如何連接,以及索引使用情況。是SQL優化的重要工具
explain詳解
下圖是explain的各個字段
首先我們需要理解各個字段的含義,才能更好用好explain這個關鍵字。
id
- id相同,執行順序從上之下
- id不同,執行順序從大到小
- id相同不同,同時存在,遵守1、2規則
下圖所示:
可以這樣理解,執行順序從大到小,先執行id為2的,然后執行id為1的(先A再B,規則1);執行順序為:第三行,第一行,第二行
select_type
查詢中每個select的查詢類型,如下:
- SIMPLE:簡單select,不使用union和子查詢
- PRIMARY:查詢中包含任何復雜的子部分,最外層的select被標記為PRIMARY
- UNION:union中第二個后面的select語句
- DEPENDENT UNION:一般是子查詢中的第二個select語句(取決于外查詢,mysql內部也有些優化)
- UNION RESULT:union的結果
- SUBQUERY:子查詢中的第一個select
- DEPENDENT SUBQUERY:子查詢中第一個select,取決于外查詢(在mysql中會有些優化,有些dependent會直接優化成simple)
- DERIVED:派生表的select(from子句的子查詢)
奇怪的是在5.7的版本中竟然只有一個SIMPLE
官網對derived table的定義是:
A derived table is an expression that generates a table within the scope of a query FROM clause.
應該是mysql內部進行了優化。
table
顯示數據來自于哪個表,有時不是真實的表的名字(虛擬表),虛擬表最后一位是數字,代表id為多少的查詢。
type
這個字段是我們優化要重點關注的字段,這個字段直接反映我們SQL的性能是否高效。
這個字段值較多,這里我只重點關注我們開發中經常用到的幾個字段:system,const,eq_ref,ref,range,index,all;
性能由好到差依次為:==system>const>eq_ref>ref>range>index>all==(一定要牢記)
- system:表只有一行記錄,這個是const的特例,一般不會出現,可以忽略
- const:表示通過索引一次就找到了,const用于比較primary key或者unique索引。因為只匹配一行數據,所以很快。
-
eq_ref:唯一性索引掃描,表中只有一條記錄與之匹配。一般是兩表關聯,關聯條件中的字段是主鍵或唯一索引。
eq_ref
-
ref:非唯一行索引掃描,返回匹配某個單獨值的所有行
ref
-
range:檢索給定范圍的行,一般條件查詢中出現了>、<、in、between等查詢
range
-
index:遍歷索引樹。通常比ALL快,因為索引文件通常比數據文件小。all和index都是讀全表,但index是從索引中檢索的,而all是從硬盤中檢索的。
index
-
all:遍歷全表以找到匹配的行
all
possible_keys
顯示可能應用在這張表中的索引,但不一定被查詢實際使用
key
實際使用的索引。
key_len
表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度。一般來說,索引長度越長表示精度越高,效率偏低;長度越短,效率高,但精度就偏低。并不是真正使用索引的長度,是個預估值。
ref
表示哪一列被使用了,常數表示這一列等于某個常數。
rows
大致找到所需記錄需要讀取的行數。
filter
表示選取的行和讀取的行的百分比,100表示選取了100%,80表示讀取了80%。
extra
一些重要的額外信息
- Using filesort:使用外部的索引排序,而不是按照表內的索引順序進行讀取。(一般需要優化)
- Using temporary:使用了臨時表保存中間結果。常見于排序order by和分組查詢group by(最好優化)
- Using index:表示select語句中使用了覆蓋索引,直接沖索引中取值,而不需要回行(從磁盤中取數據)
- Using where:使用了where過濾
- Using index condition:5.6之后新增的,表示查詢的列有非索引的列,先判斷索引的條件,以減少磁盤的IO
- Using join buffer:使用了連接緩存
- impossible where:where子句的值總是false
還有一些,基本上很少遇到,就不作說明了。