MYSQL explain執(zhí)行計劃解讀
點擊上方“碼農(nóng)編程進(jìn)階筆記”,選擇“置頂或者星標(biāo)”
Explain 查看SQL語句的執(zhí)行計劃:分析SQL執(zhí)行計劃,優(yōu)化SQL及索引策略,run faster.
EXPLAIN SELECT * from user_info WHEREid = 1; 
Explain查看查詢計劃主要包含如下信息列:查詢id、查詢類型、查詢表、掃描訪問類型、查詢可能選用的索引、查詢實際使用索引、mysql決定使用索引長度、ref 顯示哪個字段或常數(shù)與key一起被使用、估算掃描行數(shù)、額外重要信息。--重點關(guān)注加粗部分。
主要通過以上指標(biāo)評估查詢好壞,從而做出相關(guān)調(diào)整優(yōu)化,使SQL盡量最優(yōu)。
explain結(jié)果各列含義:
一、id :select查詢的序列號
二、select_type:
select查詢的類型,主要是區(qū)別 普通查詢和聯(lián)合查詢、子查詢之類的復(fù)雜查詢。
SIMPLE:查詢中不包含子查詢或者UNION
PRIMARY: 查詢中若包含任何復(fù)雜的子部分,最外層查詢被標(biāo)記為PRIMARY
SUBQUERY: 在SELECT或WHERE列表中包含了子查詢
DERIVED(衍生): 在FROM列表中包含的子查詢
UNION:UNION中的第二個或后面的SELECT語句
UNION RESULT: UNION結(jié)果
三、table: 查詢表
四、type顯示的是訪問類型,是較為重要的一個指標(biāo),結(jié)果值從好到壞依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL 一般來說,得保證查詢至少達(dá)到range級別,最好能達(dá)到ref。
ALL: 掃描全表
index: 只遍歷索引樹,直接從索引中就可以獲取數(shù)據(jù)滿足查詢, 而不需要再去查詢數(shù)據(jù)表中的數(shù)據(jù). 這樣的情況type 是index, 并且 Extra 的值是Using index.
range: 使用索引范圍查詢, 通過索引字段范圍獲取表中部分?jǐn)?shù)據(jù)記錄. 這個類型通常出現(xiàn)在 <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN() 操作中.
ref:非唯一性索引(普通索引)掃描,返回匹配某個單獨值的所有行。常見于使用非唯一索引即唯一索引的非唯一前綴進(jìn)行的查找
eq_ref:唯一性索引掃描,對于每個索引鍵,表中只有一條記錄與之匹配。常見于主鍵或唯一索引掃描
const, system: 當(dāng)MySQL對查詢某部分進(jìn)行優(yōu)化,并轉(zhuǎn)換為一個常量時,使用這些類型訪問。如將主鍵置于where列表中,MySQL就能將該查詢轉(zhuǎn)換為一個常量。system是const類型的特例,當(dāng)查詢的表只有一行的情況下, 使用system。
NULL: MySQL在優(yōu)化過程中分解語句,執(zhí)行時甚至不用訪問表或索引。
五、possible_keys: 此次查詢中可能選用的索引
六、key: 此次查詢中實際使用到的索引.如果沒有索引被選擇,鍵是NULL
七、key_len:顯示MySQL決定使用的鍵長度。表示索引中使用的字節(jié)數(shù),可通過該列計算查詢中使用的索引的長度。如果鍵是NULL,長度就是NULL。文檔提示特別注意這個值可以得出一個多重主鍵里mysql實際使用了哪一部分。
注:key_len顯示的值為索引字段的最大可能長度,并非實際使用長度,即key_len是根據(jù)表定義計算而得,不是通過表內(nèi)檢索出的。
八、ref:顯示哪個字段或常數(shù)與key一起被使用。
九、rows: 顯示此查詢一共掃描了多少行才能找到. 這個是一個估計值.
十、Extra: 包含不適合在其他列中顯示但十分重要的額外信息。
Only index,這意味著信息只用索引樹中的信息檢索出的,這比掃描整個表要快。
Using index:使用索引掃描。
using where:使用where限制,表示MySQL服務(wù)器在存儲引擎受到記錄后進(jìn)行“后過濾”(Post-filter),如果查詢未能使用索引,Using where的作用只是提醒我們MySQL將用where子句來過濾結(jié)果集。
Using filesort: MySQL中無法利用索引完成的排序操作稱為“文件排序”。它跟文件沒有任何關(guān)系,實際上是內(nèi)部的一個快速排序。
Using temporary:MySQL需要使用臨時表來存儲結(jié)果集,常見于排序和分組查詢。使用filesort和temporary的話會很吃力,WHERE和ORDER BY的索引經(jīng)常無法兼顧,如果按照WHERE來確定索引,那么在ORDER BY時,就必然會引起Using filesort,這就要看是先過濾再排序劃算,還是先排序再過濾劃算。
impossible where: 表示用不著where,一般就是沒查出來啥。
Using join buffer:改值強(qiáng)調(diào)了在獲取連接條件時沒有使用索引,并且需要連接緩沖區(qū)來存儲中間結(jié)果。如果出現(xiàn)了這個值,那應(yīng)該注意,根據(jù)查詢的具體情況可能需要添加索引來改進(jìn)能。
求一鍵三連:點贊、轉(zhuǎn)發(fā)、在看。
