1. 程式人生 > 實用技巧 >MySQL Explain詳解(轉)

MySQL Explain詳解(轉)

MySQL Explain詳解

簡介

執行計劃(query Execution plan)

語法

    explain select * from table

explain 中的列

expain出來的資訊有10列,

分別是id,select_type,table、type,partitions,possible_keys,key,key_len,ref,rows,Extra,下面對這些欄位出現的可能進行解釋:

一、ID

SQL執行的順序的標識,SQL從大到小的執行

  • ID相同時,執行順序由上至下
  • 如果是子查詢,ID的序號會遞增,ID值越大優先順序越高,越先被執行
  • ID如果相同,可以認為是一組,從上往下順序執行;在所有組中,ID值越大,優先順序越高,越先執行

二、select_type

示查詢中每個select子句的型別

  • SIMPLE:簡單的SELECT,不實用UNION或者子查詢。
  • PRIMARY:最外層SELECT。
  • UNION:第二層,在SELECT之後使用了UNION。
  • DEPENDENT UNION:UNION語句中的第二個SELECT,依賴於外部子查詢。
  • UNION RESULT:UNION的結果。
  • SUBQUERY:子查詢中的第一個SELECT。
  • DEPENDENT SUBQUERY:子查詢中的第一個SELECT,取決於外面的查詢。
  • DERIVED:匯出表的SELECT(FROM子句的子查詢)
  • MATERIALIZED:物化子查詢
  • UNCACHEABLE SUBQUERY:無法快取結果的子查詢,必須為外部查詢的每一行重新計算
  • UNCACHEABLE UNION:UNION 屬於不可快取的子查詢的第二個或後一個選擇

三、table

輸出行引用的表的名稱。這也可以是以下值之一:

  • <unionM,N,...>:該行指的是id值為M和id值為N的並集。
  • <derivedN>:該行是指用於與該行的派生表結果id的值 N。例如,派生表可以來自FROM子句中的子查詢
  • <subqueryN>:該行指的是id 值為的行的具體化子查詢的結果N

四、type

表示MySQL在表中找到所需行的方式,又稱“訪問型別”。

常用的型別有: NULL, system, const, eq_ref, ref, range, index, ALL(從左到右,效能從差到好)
以下列表描述了從最佳型別到最差型別的連線型別

  1. NULL
    MySQL在優化過程中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列裡選取最小值可以通過單獨索引查詢完成。
  2. system
    該表只有一行(如:系統表)。這是const連線型別的特例
  3. const
    該表最多隻有一個匹配行,在查詢開頭讀取。因為只有一行,所以優化器的其餘部分可以將此行中列的值視為常量。 const表非常快,因為它們只讀一次。

    SELECT * FROM tbl_name WHERE primary_key=1;
    SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2;
  4. eq_ref
    對於前面表格中的每個行組合,從該表中讀取一行。除了 system和 const型別之外,這是最好的連線型別。當連線使用索引的所有部分且索引是 索引PRIMARY KEY或UNIQUE NOT NULL索引時使用它。

    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;
  5. ref
    表示上述表的連線匹配條件,即哪些列或常量被用於查詢索引列上的值
  6. fulltext
    使用FULLTEXT 索引執行連線。
  7. ref_or_null

    SELECT * FROM ref_table WHERE key_column IS NULL;
  8. index_merge
    該指數合併訪問方法檢索與多行 range掃描和他們的結果合併到一個。此訪問方法僅合併來自單個表的索引掃描,而不掃描多個表。合併可以生成其基礎掃描的聯合,交叉或交叉聯合

    SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;
    
    SELECT * FROM tbl_name
    WHERE (key1 = 10 OR key2 = 20) AND non_key = 30;
    
    SELECT * FROM t1, t2
    WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')
    AND t2.key1 = t1.some_col;
    
    SELECT * FROM t1, t2
    WHERE t1.key1 = 1
    AND (t2.key1 = t1.some_col OR t2.key2 = t1.some_col2);
  9. unique_subquery
    此型別替換 以下形式的eq_ref某些 IN子查詢:

    value IN (SELECT primary_key FROM single_table WHERE some_expr)
  10. index_subquery
    此連線型別類似於 unique_subquery。它替換IN子查詢,但它適用於以下形式的子查詢中的非唯一索引:

    value IN (SELECT key_column FROM single_table WHERE some_expr)
  11. range
    僅檢索給定範圍內的行,使用索引選擇行。的key 輸出行中的列指示使用哪個索引。將key_len包含已使用的時間最長的關鍵部分。該ref列 NULL適用於此型別。
    range當一個鍵柱使用任何的相比於恆定可使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE,或 IN()運營商:
  12. index
    該index聯接型別是一樣的 ALL,只是索引樹被掃描。這種情況有兩種:

    ALL
    1. 如果索引是查詢的覆蓋索引,並且可用於滿足表中所需的所有資料,則僅掃描索引樹。在這種情況下,Extra專欄說 Using index。僅索引掃描通常比ALL索引的大小通常小於表資料更快 。
    2. 使用索引中的讀取執行全表掃描,以按索引順序查詢資料行。 Uses index沒有出現在 Extra列中。當查詢僅使用屬於單個索引的列時,MySQL可以使用此連線型別。
  13. 對前面表格中的每個行組合進行全表掃描。如果表是第一個未標記的表 const,通常不好,並且在所有其他情況下通常 非常糟糕。通常,您可以ALL通過新增基於常量值或早期表中的列值從表中啟用行檢索的索引來避免

五、possible_keys

該possible_keys列指示MySQL可以選擇在此表中查詢行的索引,指出MySQL能使用哪個索引在表中找到記錄,查詢涉及到的欄位上若存在索引,則該索引將被列出,但不一定被查詢使用

該列完全獨立於EXPLAIN輸出所示的表的次序。這意味著在possible_keys中的某些鍵實際上不能按生成的表次序使用。
如果該列是NULL,則沒有相關的索引。在這種情況下,可以通過檢查WHERE子句看是否它引用某些列或適合索引的列來提高你的查詢效能。如果是這樣,創造一個適當的索引並且再次用EXPLAIN檢查查詢

六、Key

key列顯示MySQL實際決定使用的鍵(索引)

如果沒有選擇索引,鍵是NULL。要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

七、key_len

表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度(key_len顯示的值為索引欄位的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的)

不損失精確性的情況下,長度越短越好

八、ref

表示上述表的連線匹配條件,即哪些列或常量被用於查詢索引列上的值

九、rows

表示MySQL根據表統計資訊及索引選用情況,估算的找到所需的記錄所需要讀取的行數

十、Extra

該Extra列 EXPLAIN輸出包含MySQL解決查詢的額外資訊。以下列表說明了此列中可能出現的值。每個專案還指示JSON格式的輸出哪個屬性顯示Extra值。對於其中一些,有一個特定的屬性。其他顯示為message 屬性的文字

十一、partitions(擴充套件)

記錄將與查詢匹配的分割槽。僅在使用PARTITIONS關鍵字時才顯示此列 。非分割槽表顯示null

原文地址:https://segmentfault.com/a/1190000017751405