Explain 詳解
在日常工作中,我們會遇到sql語句查詢速度特別慢做院,常常用到explain這個命令來查看一個這些SQL語句的執(zhí)行計劃,查看該SQL語句有沒有使用上了索引濒持,有沒有做全表掃描键耕,這都可以通過explain命令來查看。所以我們深入了解MySQL的基于開銷的優(yōu)化器柑营,還可以獲得很多可能被優(yōu)化器考慮到的訪問策略的細(xì)節(jié)屈雄,以及當(dāng)運(yùn)行SQL語句時哪種策略預(yù)計會被優(yōu)化器采用。
Explain字段詳解(重點關(guān)注加粗項)
列名 | 描述 |
---|---|
id | 在一個大的查詢語句中每個SELECT關(guān)鍵字都對應(yīng)一個唯一的id |
select_type | SELECT關(guān)鍵字對應(yīng)的那個查詢的類型 |
table | 表名 |
partitions | 匹配的分區(qū)信息 |
type | 表示表的連接類型 |
possible_keys | 表示查詢時官套,可能使用的索引 |
key | 實際上是使用的索引 |
key_len | 實際使用到的索引 長度 |
ref | 當(dāng)使用索引列等值查詢時,與索引列進(jìn)行等值匹配的對象信息 |
rows | 預(yù)估的需要讀取的記錄條數(shù) |
filtered | 某個表經(jīng)過搜索條件過濾后剩余記錄條數(shù)的百分比 |
Extra | 一些額外的信息 |
select_type解讀 (UNION:聯(lián)合查詢)
select_type的值 | 解釋
-------- |: -----
SIMPLE|簡單查詢(不使用關(guān)聯(lián)查詢或子查詢)
PRIMARY|如果包含關(guān)聯(lián)查詢或者子查詢棚亩,則最外層的查詢部分標(biāo)記primary
UNION|聯(lián)合查詢(UNION)中第二個及后面的查詢
DEPENDENT UNION|UNION中的第二個或后面的SELECT語句,取決于外面的查詢
UNION RESULT|UNION的結(jié)果虏杰,union語句中第二個select開始后面所有select
SUBQUERY|字查詢中的第一個擦訊
DEPENDENT SUBQUERY|子查詢中的第一個查詢,并且依賴外部查詢
DERIVED|派生表的SELECT, FROM子句的子查詢
MATERIALIZED|被物化的子查詢
UNCACHEABLE SUBQUERY|一個子查詢的結(jié)果不能被緩存勒虾,必須重新評估外鏈接的第一行
table 解讀
顯示這一步所訪問數(shù)據(jù)庫中表名稱(顯示這一行的數(shù)據(jù)是關(guān)于哪張表的)纺阔,有時不是真實的表名字,可能是簡稱修然,例如上面的e笛钝,d质况,也可能是第幾步執(zhí)行的結(jié)果的簡稱
type 解讀
對表訪問方式,表示MySQL在表中找到所需行的方式玻靡,又稱“訪問類型”结榄。
常用的類型有: ALL、index囤捻、range臼朗、 ref、eq_ref蝎土、const视哑、system、NULL(從左到右誊涯,性能從差到好)
type的值 | 解釋 |
---|---|
all | Full Table Scan挡毅, MySQL將遍歷全表以找到匹配的行 |
system | 查詢對象表只有一行數(shù)據(jù),且只能用于MyISAM和Memory引擎的表暴构,這是最好的情況 |
const | 基于主鍵或唯一索引查詢跪呈,最多返回一條結(jié)果 |
eq_ref | 類似ref,區(qū)別就在使用的索引是唯一索引取逾,對于每個索引鍵值耗绿,表中只有一條記錄匹配,簡單來說菌赖,就是多表連接中使用primary key或者 unique key作為關(guān)聯(lián)條件 |
ref | 表示上述表的連接匹配條件缭乘,即哪些列或常量被用于查找索引列上的值 |
fulltext | 全文檢索 |
ref_or_null | 表連接類型是ref,但進(jìn)行掃描的索引列中可能包含NULL值 |
index_merge | l利用多個索引 |
unique_subquery | 子查詢中使用唯一索引 |
index_subquery | 子查詢中使用普通索引 |
range | 只檢索給定范圍的行琉用,使用一個索引來選擇行 |
index | Full Index Scan堕绩,index與ALL區(qū)別為index類型只遍歷索引樹 |
null | MySQL在優(yōu)化過程中分解語句,執(zhí)行時甚至不用訪問表或索引邑时,例如從一個索引列里選取最小值可以通過單獨索引查找完成 |
possible_keys 解讀
指出MySQL能使用哪個索引在表中找到記錄奴紧,查詢涉及到的字段上若存在索引,則該索引將被列出晶丘,但不一定被查詢使用(該查詢可以利用的索引黍氮,如果沒有任何索引顯示 null)
該列完全獨立于EXPLAIN輸出所示的表的次序。這意味著在possible_keys中的某些鍵實際上不能按生成的表次序使用浅浮。
如果該列是NULL沫浆,則沒有相關(guān)的索引。在這種情況下滚秩,可以通過檢查WHERE子句看是否它引用某些列或適合索引的列來提高你的查詢性能专执。如果是這樣,創(chuàng)造一個適當(dāng)?shù)乃饕⑶以俅斡肊XPLAIN檢查查詢
Key 解讀
key列顯示MySQL實際決定使用的鍵(索引)郁油,必然包含在possible_keys中
如果沒有選擇索引本股,鍵是NULL攀痊。要想強(qiáng)制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX拄显、USE INDEX或者IGNORE INDEX苟径。
key_len 解讀
表示索引中使用的字節(jié)數(shù),可通過該列計算查詢中使用的索引的長度(key_len顯示的值為索引字段的最大可能長度躬审,并非實際使用長度棘街,即key_len是根據(jù)表定義計算而得,不是通過表內(nèi)檢索出的)
不損失精確性的情況下盒件,長度越短越好
ref 解讀
列與索引的比較蹬碧,表示上述表的連接匹配條件,即哪些列或常量被用于查找索引列上的值
rows 解讀
估算出結(jié)果集行數(shù)炒刁,表示MySQL根據(jù)表統(tǒng)計信息及索引選用情況恩沽,估算的找到所需的記錄所需要讀取的行數(shù)
Extra 解讀
Extra 常見的值 | 解釋 | 例子 |
---|---|---|
Using filesort | 當(dāng)Query中包含 order by 操作,而且無法利用索引完成的排序操作稱為“文件排序” | explain select * from t order by createTime翔始; |
Using temporary | 表示MySQL需要使用臨時表來存儲結(jié)果集罗心,常見于排序和分組查詢,常見 group by ; order by | explain select * from t order by createTime城瞎; |
Using index | 使用覆蓋索引 | explain select id from t where id=‘222’渤闷; |
Using where | 不用讀取表中所有信息,僅通過索引就可以獲取所需數(shù)據(jù)脖镀,這發(fā)生在對表的全部的請求列都是同一個索引的部分的時候飒箭,表示mysql服務(wù)器將在存儲引擎檢索行后再進(jìn)行過濾 | explain select * from t where createTime =‘2020-04-23 00:00:00’; |
Impossible WHERE | 這個值強(qiáng)調(diào)了where語句會導(dǎo)致沒有符合條件的行(通過收集統(tǒng)計信息不可能存在結(jié)果) | explain select * from t where 1<0蜒灰; |
Using jion buffer (Block Nested Loop) | 改值強(qiáng)調(diào)了在獲取連接條件時沒有使用索引弦蹂,并且需要連接緩沖區(qū)來存儲中間結(jié)果。如果出現(xiàn)了這個值强窖,那應(yīng)該注意凸椿,根據(jù)查詢的具體情況可能需要添加索引來改進(jìn)能。 | explain select * from t straight jion t1 on t.createTime =t1.createTime 翅溺; |
Using index condition | 先條件過濾索引,在查數(shù)據(jù) | explain select * from t where a>900 and a like '%9'脑漫; |
select tables optimized away | 這個值意味著僅通過使用索引,優(yōu)化器可能僅從聚合函數(shù)結(jié)果中返回一行 | explain select max(a) from t 咙崎; |
No tables used | Query語句中使用from dual 或不含任何from子句 | explain select now() from dual; |
總結(jié):
? EXPLAIN不會告訴你關(guān)于觸發(fā)器优幸、存儲過程的信息或用戶自定義函數(shù)對查詢的影響情況
? EXPLAIN不考慮各種Cache
? EXPLAIN不能顯示MySQL在執(zhí)行查詢時所作的優(yōu)化工作
? 部分統(tǒng)計信息是估算的,并非精確值
? EXPALIN只能解釋SELECT操作褪猛,其他操作要重寫為SELECT后查看執(zhí)行計劃劈伴。