一. EXPLAIN執(zhí)行計(jì)劃分析
EXPLAIN可以幫助開(kāi)發(fā)人員分析SQL問(wèn)題,EXPLAIN顯示了MySQL如何使用使用SQL執(zhí)行計(jì)劃,可以幫助開(kāi)發(fā)人員寫(xiě)出更優(yōu)化的查詢語(yǔ)句。使用方法,在select語(yǔ)句前加上EXPLAIN就可以了。
舉例:
下面是一個(gè)最普通的查詢語(yǔ)句,用EXPLAIN進(jìn)行分析演示。
EXPLAIN SELECT * FROM student;
結(jié)果:
結(jié)果的列的說(shuō)明如下:
id :SELECT識(shí)別符。這是SELECT查詢序列號(hào)。這個(gè)不重要。
select_type:表示SELECT語(yǔ)句的類型。
● simple:簡(jiǎn)單select(不使用union或子查詢)。
● primary:最外面的select。
● union:union中的第二個(gè)或后面的select語(yǔ)句。
● dependent union:union中的第二個(gè)或后面的select語(yǔ)句,取決于外面的查詢。
● union result:union的結(jié)果。
● subquery:子查詢中的第一個(gè)select。
● dependent subquery:子查詢中的第一個(gè)select,取決于外面的查詢。
● derived:導(dǎo)出表的select(from子句的子查詢)。
table:顯示這查詢的數(shù)據(jù)是關(guān)于哪張表的。
type:區(qū)間索引,這是重要的列,顯示連接使用了何種類型。從最好到最差的連接類型為。
system > const > eq_ref > ref > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般來(lái)說(shuō),得保證查詢至少達(dá)到range級(jí)別,最好能達(dá)到ref。
● system:表僅有一行,這是const類型的特列,平時(shí)不會(huì)出現(xiàn),這個(gè)也可以忽略不計(jì)。
● const:數(shù)據(jù)表最多只有一個(gè)匹配行,因?yàn)橹黄ヅ湟恍袛?shù)據(jù),所以很快。
● eq_ref:mysql手冊(cè)是這樣說(shuō)的:"對(duì)于每個(gè)來(lái)自于前面的表的行組合,從該表中讀取一行。這可能是最好的聯(lián)接類型,除了const類型。它用在一個(gè)索引的所有部分被聯(lián)接使用并且索引是UNIQUE或PRIMARY KEY"。eq_ref可以用于使用=比較帶索引的列。
● ref:查詢條件索引既不是UNIQUE也不是PRIMARY KEY的情況。ref可用于=或<或>操作符的帶索引的列。
● ref_or_null:該聯(lián)接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行。在解決子查詢中經(jīng)常使用該聯(lián)接類型的優(yōu)化。
● index_merge:該聯(lián)接類型表示使用了索引合并優(yōu)化方法。在這種情況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長(zhǎng)的關(guān)鍵元素。
● unique_subquery:該類型替換了下面形式的IN子查詢的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一個(gè)索引查找函數(shù),可以完全替換子查詢,效率更高。
● index_subquery:該聯(lián)接類型類似于unique_subquery??梢蕴鎿QIN子查詢,但只適合下列形式的子查詢中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
● range:只檢索給定范圍的行,使用一個(gè)索引來(lái)選擇行。
● index:該聯(lián)接類型與ALL相同,除了只有索引樹(shù)被掃描。這通常比ALL快,因?yàn)樗饕募ǔ1葦?shù)據(jù)文件小。
● ALL:對(duì)于每個(gè)來(lái)自于先前的表的行組合,進(jìn)行完整的表掃描(性能最差)。
possible_keys:指出MySQL能使用哪個(gè)索引在該表中找到行。如果是空的,沒(méi)有相關(guān)的索引。這時(shí)要提高性能,可通過(guò)檢驗(yàn)WHERE子句,看是否引用某些字段,或者檢查字段不是適合索引。
key:實(shí)際使用到的索引。如果為NULL,則沒(méi)有使用索引。如果為primary的話,表示使用了主鍵。
key_len:最長(zhǎng)的索引寬度。如果鍵是NULL,長(zhǎng)度就是NULL。在不損失精確性的情況下,長(zhǎng)度越短越好。
ref:顯示使用哪個(gè)列或常數(shù)與key一起從表中選擇行。
rows:顯示MySQL認(rèn)為它執(zhí)行查詢時(shí)必須檢查的行數(shù)。
Extra:執(zhí)行狀態(tài)說(shuō)明,該列包含MySQL解決查詢的詳細(xì)信息。
● Distinct:MySQL發(fā)現(xiàn)第1個(gè)匹配行后,停止為當(dāng)前的行組合搜索更多的行。
● Not exists:MySQL能夠?qū)Σ樵冞M(jìn)行LEFT JOIN優(yōu)化,發(fā)現(xiàn)1個(gè)匹配LEFT JOIN標(biāo)準(zhǔn)的行后,不再為前面的的行組合在該表內(nèi)檢查更多的行。
● range checked for each record (index map: #):MySQL沒(méi)有發(fā)現(xiàn)好的可以使用的索引,但發(fā)現(xiàn)如果來(lái)自前面的表的列值已知,可能部分索引可以使用。
● Using filesort:MySQL需要額外的一次傳遞,以找出如何按排序順序檢索行。
● Using index:從只使用索引樹(shù)中的信息而不需要進(jìn)一步搜索讀取實(shí)際的行來(lái)檢索表中的列信息。
● Using temporary:為了解決查詢,MySQL需要?jiǎng)?chuàng)建一個(gè)臨時(shí)表來(lái)容納結(jié)果。
● Using where:WHERE 子句用于限制哪一個(gè)行匹配下一個(gè)表或發(fā)送到客戶。
● Using sort_union(...), Using union(...), Using intersect(...):這些函數(shù)說(shuō)明如何為index_merge聯(lián)接類型合并索引掃描。
● Using index for group-by:類似于訪問(wèn)表的Using index方式,Using index for group-by表示MySQL發(fā)現(xiàn)了一個(gè)索引,可以用來(lái)查 詢GROUP BY或DISTINCT查詢的所有列,而不要額外搜索硬盤(pán)訪問(wèn)實(shí)際的表。