EXPLAIN提供了有關(guān)如何執(zhí)行SQL語句的信息绍移,用于select,delete讥电,insert,update恩敌,replace等語句中。在select語句中使用EXPLAIN將返回一行信息(每個(gè)表對(duì)應(yīng)一行纠炮,包含臨時(shí)表),按照處理語句時(shí)的順序顯示恢口。存在表連接時(shí)孝宗,使用循環(huán)嵌套的方式解析所有連接,也就是說從第一個(gè)表中讀取一行然后在第二個(gè)表中匹配所有符合條件的行耕肩,然后再在第三個(gè)表……。當(dāng)所有的表處理完后看疗,輸出選中的列并且返回表清單直到找到一個(gè)有更多匹配行的表。從該表讀入一行并繼續(xù)處理下一個(gè)表两芳。EXPLAIN的輸出包含分區(qū)信息摔寨,對(duì)于select語句和DESCRIBE相似(通常情況下DESCRIBE用于獲取表結(jié)構(gòu)的信息,而EXPLAIN用于語句的執(zhí)行計(jì)劃怖辆,即解釋如何執(zhí)行查詢)是复。
EXPLAIN輸出列
每行輸出代表一個(gè)表的相關(guān)信息,包含以下字段(JSON 名稱為使用FORMAT=JSON時(shí)的key)
Column | JSON名稱 | 說明 |
---|---|---|
id | select_id | SELECT標(biāo)識(shí) |
select_type | 無 | SELECT類型 |
table | table_name | 輸出行所應(yīng)用的表 |
partitions | partitions | 匹配分區(qū) |
type | access_type | 連接類型 |
possible_keys | possible_keys | 可能選擇的索引 |
key | key | 實(shí)際選擇的索引 |
key_len | key_length | key的長(zhǎng)度 |
ref | ref | The columns compared to the index |
rows | rows | 估計(jì)要掃描的檢查的行數(shù) |
filtered | filtered | 按條件過濾行的百分比 |
Extra | 無 | 附加信息 |
- id
SELECT識(shí)別符逗余,SELECT的查詢序列號(hào)季惩。 - select_type
select類型可以是以下值:
select_type 值 | JSON 名稱 | 說明 |
---|---|---|
SIMPLE | 無 | 簡(jiǎn)單select語句 (未使用子查詢和union) |
PRIMARY | 無 | 最外層select |
UNION | 無 | union語句中的第二個(gè)往后的select語句 |
DEPENDENT UNION | dependent (true) | union語句中的第二個(gè)往后的select語句, 取決于外層查詢 |
UNION RESULT | union_result | 一個(gè)union的結(jié)果 |
SUBQUERY | 無 | 第一個(gè)子查詢 |
DEPENDENT | SUBQUERY dependent (true) | 第一個(gè)子查詢,取決于外層查詢 |
DERIVED | 無 | 派生表 (from 子句中的子查詢) |
MATERIALIZED | materialized_from_subquery | 物化子查詢(子查詢通常緩存在內(nèi)存或臨時(shí)表里) |
UNCACHEABLE SUBQUERY | cacheable (false) | 不能將子查詢結(jié)果緩存并且必須對(duì)外部查詢的每一行重新評(píng)估 |
UNCACHEABLE UNION | cacheable (false) | 第二個(gè)往后的unioon不可緩存子查詢(見UNCACHEABLE SUBQUERY) |
注:在查詢緩存中子查詢的緩存行和查詢結(jié)果的緩存不同画拾,子查詢緩存發(fā)生在查詢期間,而查詢緩存在查詢完成后才進(jìn)行存儲(chǔ)結(jié)果青抛。具體查詢?nèi)绾尉彺妫?qǐng)參照:https://dev.mysql.com/doc/refman/5.7/en/query-cache-operation.html
table
引用表的名稱适室。如果使用別名,這里將顯示別名捣辆。也可以是以下幾種情況:
<unionM,N>嘶居,<derivedN>罪帖,subqueryN>邮屁。M和N為返回行的idpartitions
記錄由查詢匹配的分區(qū)。該值為NULL表示用于非分區(qū)表佑吝。(關(guān)于表分區(qū)可用show create table查看)type
連接類型。依次從好到差:system
表中只有一行(系統(tǒng)表)芋忿。是const連接類型的特殊情況 。const
使用唯一索引或者主鍵痹仙,返回記錄一定只有一行,通常是const开仰。
在下面的查詢中,tbl_name可以用于const表
SELECT * from tbl_name WHERE primary_key = 1
SELECT * from tbl_name WHERE primary_key_part1 = 1 AND primary_key_part2 = 2
eq_ref
對(duì)于每個(gè)來自于前表的行組合,從該表中讀取一行众弓。它使用一個(gè)索引連接并且索引是UNIQUE或PRIMARY KEY恩溅,這可能是除了system和const類型外最好的連接類型。eq_ref可以是使用 = 操作符比較索引列谓娃,比較值可以是常量或一個(gè)列的表達(dá)式
在下面的查詢中脚乡,使用eq_ref連接進(jìn)行處理
SELECT * FROM ref_table,other_table WHERE ref_table.key_column = other_table.column
SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1 = other_table.column AND ref_table.key_column_part2 = 1
ref
對(duì)于每個(gè)來自于前表的行組合,讀取所有匹配索引值的行奶稠。若索引不是UNIQUE或PRIMARY KEY(也就是說連接不能返回單行的話)則類型是ref弦悉。如果匹配少量的行窒典,該連接類型還是不錯(cuò)的稽莉。
在下面的查詢中涩搓,使用ref連接進(jìn)行處理
SELECT * FROM ref_table WHERE key_column = expr
SELECT * FROM ref_table,other_table WHERE ref_table.key_column = other_table.column
SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1 = other_table.column AND ref_table.key_column_part2 = 1
fulltext
全文索引檢索,要注意良拼,全文索引的優(yōu)先級(jí)很高,若全文索引和普通索引同時(shí)存在時(shí)庸推,優(yōu)先選擇使用全文索引浇冰。ref_or_null
該聯(lián)接類型同ref,只是添加了專門包含NULL值的行肘习。
在下面的查詢中,使用ref_or_null聯(lián)接來處理ref_tables:
SELECT * FROM ref_table WHERE key_column = expr OR key_column IS NULL
index_merge
使用兩個(gè)及以上的索引合并查詢漂佩,常用or或and
在下面的查詢中,使用ref_or_null聯(lián)接來處理ref_tables:
SELECT * FROM ref_table WHERE key_column1 = expr1 and key_column2 = expr2
unique_subquery
這個(gè)類型使用in的子查詢替換eq_ref
value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一個(gè)索引查找函數(shù)养葵,可以完全替換子查詢瘩缆,效率更高index_subquery
該聯(lián)接類型類似于unique_subquery。適用于子查詢包含非唯一索引的情況。
value IN (SELECT key_column FROM single_table WHERE some_expr)
range
索引范圍掃描爽锥,常見于使用>,<,is null,between ,in ,like等運(yùn)算符的查詢中。index
該連接類型類似于ALL氯夷,除了索引樹被掃描靶擦。通常有兩種方式:
1:如果索引是用于滿足表中所需的所有數(shù)據(jù)時(shí)的覆蓋索引,則僅掃描索引樹玄捕。這種情況下,Extra中包含 Using index枚粘。因?yàn)樗? 引比表數(shù)據(jù)更小,所以這種情況通常比All更快福也。
2:使用索引讀取執(zhí)行全表掃描攀圈,按索引順序查找數(shù)據(jù)行暴凑。Extra中不包含 Using index赘来。
當(dāng)查詢只使用作為單索引一部分的列時(shí),MySQL可以使用該聯(lián)接類型嗦篱。ALL
全表掃描然后過濾忧风,通常性能很差默色。possible_keys
表示可以選擇哪些索引來查找此表中的行狮腿。注意,該列完全獨(dú)立于EXPLAIN輸出所示的表的次序吃度。這意味著在possible_keys中的某些鍵實(shí)際上不能按生成的表次序使用。如果該列是NULL椿每,則沒有相關(guān)的索引。在這種情況下间护,可以通過檢查WHERE子句看它是否引用某些適合使用索引的列來提高你的查詢性能。這樣法精,創(chuàng)建一個(gè)合適的索引并且再次用EXPLAIN檢查查詢key
實(shí)際使用的索引,如果沒有選擇索引則為NULLkey_len
索引長(zhǎng)度搂蜓。如果索引是NULL辽装,則長(zhǎng)度為NULLref
ref列顯示使用哪個(gè)列或常數(shù)與索引匹配行。rows
執(zhí)行查詢時(shí)必須檢查的行數(shù)拾积。filtered
該filtered列指示將由表?xiàng)l件過濾的表行的估計(jì)百分比。也就是說此再,rows 顯示估計(jì)的行數(shù), rows× filtered/ 100顯示與先前表相連接的行數(shù)。Extra
包含有關(guān)如何解析查詢的其他信息摘符。參照https://dev.mysql.com/doc/refman/5.7/en/explain-output.html#explain_extra