簡單地整理一下explain的知識

輸出的一些相關信息,只有瞭解這些相關信息到底是要作什麼,才能經過執行計劃更加準確的明白如何去優化一個select ;函數

id : 標識,查詢序列號;性能

select_type :  select的類型;優化

    SIMPLE   簡單SELECT(不使用UNION或子查詢)
    PRIMARY  最外面的SELECT
    UNION       UNION中的第二個或後面的SELECT語句
    DEPENDENT UNION    UNION中的第二個或後面的SELECT語句,取決於外面的查詢
    UNION RESULT    UNION的結果。
    SUBQUERY   子查詢中的第一個SELECT
    DEPENDENT SUBQUERY   子查詢中的第一個SELECT,取決於外面的查詢
    DERIVED  導出表的SELECT(FROM子句的子查詢)spa

table : 輸出的行所引用的表 ;指針

type :  聯接類型;排序

    system  表僅有一行(=系統表)。這是const聯接類型的一個特例
    const     表最多有一個匹配行,它將在查詢開始時被讀取。由於僅有一行,在這行的列值可被優化器剩餘部分認爲是常數。 const表很快,由於它們只讀取一次!const用於用常數值比較PRIMARY KEY或UNIQUE索引的全部部分時 ;索引

    eq_ref     對於每一個來自於前面的表的行組合,從該表中讀取一行。這多是最好的聯接類型,除了const類型。它用在一個索引的全部部分被聯接使用而且索引是UNIQUE或PRIMARY KEY。eq_ref能夠用於使用= 操做符比較的帶索引的列。比較值能夠爲常量或一個使用在該表前面所讀取的表的列的表達式。字符串

       例如: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;io

    ref           對於每一個來自於前面的表的行組合,全部有匹配索引值的行將從這張表中讀取。若是聯接只使用鍵的最左邊的前綴,或若是鍵不是UNIQUE或PRIMARY KEY(換句話說,若是聯接不能基於關鍵字選擇單個行的話),則使用ref。若是使用的鍵僅僅匹配少許行,該聯接類型是不錯的。ref能夠用於使用=或<=>操做符的帶索引的列。table

        例如 : 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;

    ref_or_null  該聯接類型如同ref,可是添加了MySQL能夠專門搜索包含NULL值的行。在解決子查詢中常用該聯接類型的優化。

        例如  : SELECT * FROM ref_table   WHERE key_column=expr OR key_column IS NULL;

    index_merge  該聯接類型表示使用了索引合併優化方法。在這種狀況下, key列包含了使用的索引的清單, key_len包含了使用的索引的最長的關鍵元素 ; 

    unique_subquery  該類型替換了下面形式的IN子查詢的ref:value IN (SELECT primary_key FROM single_table WHERE some_expr)  unique_subquery是一個索引查找函數,能夠徹底替換子查詢,效率更高。

          例如 :value IN (SELECT key_column FROM single_table WHERE some_expr)

    index_subquery    該聯接類型相似於unique_subquery。能夠替換IN子查詢,但只適合下列形式的子查詢中的非惟一索引

         例如:  value IN (SELECT key_column FROM single_table WHERE some_expr)

    range  只檢索給定範圍的行,使用一個索引來選擇行。 key列顯示使用了哪一個索引。 key_len包含所使用索引的最長關鍵元素。在該類型中ref列爲NULL。當使用=、 <>、 >、 >=、 <、 <=、 IS NULL、 <=>、 BETWEEN或者IN操做符,用常量比較關鍵字列時,可使用range ; 

          例如 : SELECT * FROM tbl_name
                        WHERE key_column = 10;
                        SELECT * FROM tbl_name
                        WHERE key_column BETWEEN 10 and 20;
                        SELECT * FROM tbl_name
                        WHERE key_column IN (10,20,30);
                        SELECT * FROM tbl_name
                        WHERE key_part1= 10 AND key_part2 IN (10,20,30);

    index   該聯接類型與ALL相同,除了只有索引樹被掃描。這一般比ALL快,由於索引文件一般比數據文件小, 當查詢只使用做爲單索引一部分的列時, MySQL可使用該聯接類型。

    ALL    對於每一個來自於先前的表的行組合,進行完整的表掃描。若是表是第一個沒標記const的表,這一般很差,而且一般在它狀況下不好。一般能夠增長更多的索引而不要使用ALL,使得行能基於前面的表中的常數值或列值被檢索出
 

possible_keys : possible_keys列指出MySQL能使用哪一個索引在該表中找到行。注意,該列徹底獨立於EXPLAIN輸出所示的表的次序。這意味着在possible_keys中的某些鍵實際上不能按生成的表次序使用。若是該列是NULL,則沒有相關的索引。在這種狀況下,能夠經過檢查WHERE子句看是否它引用某些列或適合索引的列來提升你的查詢性能。若是是這樣,創造一個適當的索引而且再次用EXPLAIN檢查查詢 ; 

key  :   key列顯示MySQL實際決定使用的鍵(索引)。若是沒有選擇索引,鍵是NULL。要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、 USE INDEX或者IGNORE INDEX。

key_len  :  key_len列顯示MySQL決定使用的鍵長度。若是鍵是NULL,則長度爲NULL。注意經過key_len值咱們能夠肯定MySQL將實際使用一個多部關鍵字的幾個部分

ref  :  ref列顯示使用哪一個列或常數與key一塊兒從表中選擇行

rows   :  rows列顯示MySQL認爲它執行查詢時必須檢查的行數

Extra  :  該列包含MySQL解決查詢的詳細信息。下面解釋了該列能夠顯示的不一樣的文本字符串

    Distinct    MySQL發現第1個匹配行後,中止爲當前的行組合搜索更多的行

    Not exists   MySQL可以對查詢進行LEFT  JOIN優化,發現1個匹配LEFT JOIN標準的行後,再也不爲前面的的行組合在該表內檢查更多的行。

            例如: SELECT * 從t1 LEFT JOIN t2 ON t1.id=t2.id  WHERE t2.id IS NULL;

    range checked for each record (index map: #)   MySQL沒有發現好的可使用的索引,但發現若是來自前面的表的列值已知,可能部分索引可使用。對前面的表的每一個行組合, MySQL檢查是否可使用range或index_merge訪問方法來索取行。 不一樣的是前面表的全部列值已知而且認爲是常量。這並不很快,但比執行沒有索引的聯接要快得多 ;

    Using filesort    MySQL須要額外的一次傳遞,以找出如何按排序順序檢索行。經過根據聯接類型瀏覽全部行併爲全部匹配WHERE子句的行保存排序關鍵字和行的指針來完成排序。而後關鍵字被排序,並按排序順序檢索行 ;

    Using index   從只使用索引樹中的信息而不須要進一步搜索讀取實際的行來檢索表中的列信息。當查詢只使用做爲單一索引一部分的列時,可使用該策略 ; 

    Using temporary  爲了解決查詢, MySQL須要建立一個臨時表來容納結果。典型狀況如查詢包含能夠按不一樣狀況列出列的GROUP BY和ORDER BY子句時。

    Using where   WHERE子句用於限制哪個行匹配下一個表或發送到客戶。除非你專門從表中索取或檢查全部行,若是Extra值不爲Using where而且表聯接類型爲ALL或index,查詢可能會有一些錯誤。若是想要使查詢儘量快,應找出Using filesort 和Using temporary的Extra值 ;

    sing sort_union(...), Using union(...), Using intersect(...)    這些函數說明如何爲index_merge聯接類型合併索引掃描

    Using index for group-by    相似於訪問表的Using index方式, Using index for group-by表示MySQL發現了一個索引,能夠用來查詢GROUP BY或DISTINCT查詢的全部列,而不要額外搜索硬盤訪問實際的表。而且,按最有效的方式使用索引,以便對於每一個組,只讀取少許索引條目。

相關文章
相關標籤/搜索