MySQL執行計劃分析

 閱讀大約需要1分鐘

MySQL執行計劃分析

列名含義
idid列,表示查詢中執行select子句或操作表的順序。
select_type查詢類型,主要是用於區分普通查詢、聯合查詢、子查詢等複雜的查詢。
table表明對應行正在訪問的是哪個表。
partitions查詢涉及到的分區。
type訪問類型,決定如何查找表中的行。
possible_keys查詢可以使用哪些索引。
key實際使用的索引,如果為NULL,則沒有使用索引。
key_len索引中使用的字節數,查詢中使用的索引的長度(最大可能長度),並非實際使用長度,理論上長度越短越好。
ref顯示索引的那一列被使用。
rows估算出找到所需行而要讀取的行數。
filtered返回結果的行數佔讀取行數的百分比,值越大越好。
Extra額外信息

1. id列

id列是一個編號,用於標識SELECT查詢的序列號,表示執行SQL查詢過程中SELECT子句或操作表的順序。

如果在SQL中沒有子查詢或關聯查詢,那麼id列都將顯示一個1。否則,內層的SELECT語句一般會順序編號。

id列分為三種情況:

1)id相同 如下普通查詢,沒有子查詢。

2)id不同 如果存在子查詢,id的序號會遞增,id值越大優先級越高,越先被執行。

3)id相同又不同 1)、2)兩種情況同時存在。 id如果相同,認為是一組,從從上往下執行。在所有組中,id值越大,優先級越高,越先執行。

2.select_type列

select_type列表示對應行的查詢類型,是簡單查詢還是複雜查詢,主要用於區分普通查詢、聯合查詢、子查詢等複雜的查詢。

select_type列有如下值:

select_type值說明
SIMPLE簡單查詢,意味著不包括子查詢或UNION。
PRIMARY查詢中包含任何復雜的子部分,最外層查詢則被標記為PRIMARY
SUBQUERY在select 或where列表中包含了子查詢
DERIVED表示包含在from子句的子查詢中的select,MySQL會遞歸執行並將結果放到一個臨時表中,稱其為“派生表”,因為該臨時表是從子查詢中派生而來的。
UNION第二個select出現在UNION之後,則被標記為UNION。
UNION RESULT從UNION表獲取結果的select。

3.table列

table列表示對應行正在執行的哪張表,指代對應表名,或者該表的別名(如果SQL中定義了別名)。

4.partitions列

查詢涉及到的分區。

5.type列

type列指代訪問類型,是MySQL決定如何查找表中的行,是SQL查詢優化中一個很重要的指標,擁有很多值,依次從最差到最優:

ALL < index < range < index_subquery < unique_subquery < index_merge < ref_or_null < fulltext < ref <  eq_ref <   const  < system

1)ALL

眾所周知的全表掃描,表示通過掃描整張表來找到匹配的行,很顯然這樣的方式查詢速度很慢。 這種情況,性能最差,在寫SQL時盡量避免此種情況的出現。

在平時寫SQL時,避免使用select *,就不難理解了。換言之,是為了避免全表掃描,因為全面掃描是性能最差的。

2)index

全索引掃描,和全表掃描ALL類似,掃描表時按索引次序進行,而不是按行掃描,即:只遍歷索引樹。 index與ALL雖然都是讀全表,但index是從索引中讀取,而ALL是從硬盤讀取。顯然,index性能上優於ALL,合理的添加索引將有助於性能的提升。

3)range

只檢索給定範圍的行,使用一個索引來選擇行。 key列顯示使用了那個索引。一般就是在where語句中出現了bettween、<、>、in等的查詢。這種索引列上的範圍掃描比全索引掃描index要好。

舉例如下: explain select * from film where film_id between 1 and 10;

4)ref

非唯一性索引掃描,返回匹配某個單獨值的所有行。本質是也是一種索引訪問,它返回所有匹配某個單獨值的行,然而它可能會找到多個符合條件的行,所以它屬於查找和掃描的混合體。 此類型只有當使用非唯一索引或者唯一索引的非唯一性前綴時,才會發生。

5)eq_ref

唯一索引掃描。常見於主鍵或唯一索引掃描。

6)const

通過索引一次就能找到,const用於比較primary key 或者unique索引。因為只需匹配一行數據,所有很快。如果將主鍵置於where列表中,mysql就能將該查詢轉換為一個const。 舉例如下: show index from film; explain select * from film where film_id = 1;

7)system

表只有一行記錄,這是const類型的特例,比較少見,如:系統表。

6. possible_keys列

顯示在查詢中使用了哪些索引。

7. key列

實際使用的索引,如果為NULL,則沒有使用索引。查詢中如果使用了覆蓋索引,則該索引僅出現在key列中。 possible_keys列表明哪一個索引有助於更高效的查詢,而key列表明實際優化採用了哪一個索引可以更加高效。 舉例如下: show index from film_actor; explain select actor_id,film_id from film_actor;

8. key_len列

表示索引中使用的字節數,查詢中使用的索的長度(最大可能長度),並非實際使用長度,理論上長度越短越好。 key_len是根據表定義計算而得的,不是通過表內檢索出的。

9. ref列

表示在key列記錄的索引中查找值,所用的列或常量const。

10. rows列

估算出找到所需行而要讀取的行數。 這個數字是內嵌循環關聯計劃裡的循環數,它並不是最終從表中讀取出來的行數,而是MySQL為了找到符合查詢的那些行而必須讀取行的平均數,只能作為一個相對數來進行衡量。

11. filtered列

返回結果的行數佔讀取行數的百分比,值越大越好。

12. Extra列

額外信息,但又十分重要。

常見的值如下:

1)Using index 表示SQL中使用了覆蓋索引。

2)Using where 許多where條件裡是涉及索引中的列,當它讀取索引時,就能被存儲引擎檢驗,因此不是所有帶·where子句的查詢都會顯示“Using where”。

3)Using temporary 對查詢結果排序時,使用了一個臨時表,常見於order by 和group by。

4)Using filesort 對數據使用了一個外部的索引排序,而不是按照表內的索引進行排序讀取。也就是說MySQL無法利用索引完成的排序操作成為“文件排序”。

相關文章

SQL優化技巧總結