MySQL Explain的使用

奮鬥的小青年_發表於2016-09-25

MySQL Query Optimizer 通過我們執行Explain命令來告訴我們它將使用什麼樣的執行計劃來優化我們的Query。所以,Explain是在優化Query的時候最直接有效的驗證我們想法的工具。

下面用Explain命令來看一下我們sql語句的執行計劃。

mysql> explain select emp_no,count(*) from employees\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: employees
         type: index
possible_keys: NULL
          key: PRIMARY
      key_len: 4
          ref: NULL
         rows: 299342
        Extra: Using index
1 row in set (0.00 sec)

下面看一下MySql Explain功能中給我展示的各種資訊的解釋

ID

         Query Optimizer所選定的執行計劃中查詢的序列號。

Select_type

         所使用的查詢型別,主要有一下幾種查詢型別

        DEPENDENTSUBQUERY:子查詢中內層的第一個SELECT,依賴於外部查詢的結果集。

        DEPENDENTUNION:子查詢中的UNION,且為UNION中從第二個SELECT開始的所有SELECT,同樣依賴於外部查詢的結果集。

        PRIMARY:子查詢中的最外層查詢,注意並不是主鍵查詢。

        SIMPLE:除子查詢或者UNION之外的其他查詢;

        SUBQUERY:子查詢內部查詢的第一個SELECT,結果不依賴於外部查詢結果集。

        UNCACHEABLESUBQUERY:結果集無法快取的子查詢。

        UNION:UNION語句中第二個SELECT開始的後面所有SELECT,第一個SELECT為PRIMARY

        UNIONRESULT:UNION中的合併結果。

Table

         顯示這一步所訪問的資料庫中的表的名稱

Type

          告訴我們對錶所使用的訪問方式,主要包含如下集中型別

                   all:全表掃描

         const:讀常量,且最多隻會有一條記錄匹配,由於是常量,所以實際上只需要讀一次;

         eq_ref:最多隻會有一條匹配結果,一般是通過主鍵或者唯一鍵索引來訪問;

                   index:全索引掃描;

                   index_merge:查詢中同時使用兩個(或更多)索引,然後對索引結果進行 merge 之後再讀取表資料;

                   index_subquery:子查詢中的返回結果欄位組合是一個索引(或索引組合),但不是一個主鍵或者唯一索引;

                   rang:索引範圍掃描;

                   ref:Join 語句中被驅動表索引引用查詢;

                   ref_or_null:與 ref 的唯一區別就是在使用索引引用查詢之外再增加一個空值的查詢;

                   system:系統表,表中只有一行資料.

                   unique_subquery:子查詢中的返回結果欄位組合是主鍵或者唯一約束;

                   Possible_keys: 該查詢可以利用的索引. 如果沒有任何索引可以使用,就會顯示成null,這一項內容對於優化時候索引的調整非常重要.

          Key:MySQL Query Optimizer 從 possible_keys 中所選擇使用的索引.

          Key_len:被選中使用索引的索引鍵長度.

          Ref:列出是通過常量(const),還是某個表的某個欄位(如果是 join)來過濾(通過 key)的.

          Rows:MySQL Query Optimizer 通過系統收集到的統計資訊估算出來的結果集記錄條數.

Extra

         查詢中每一步實現的額外細節資訊,主要可能會是以下內容:

        Distinct:查詢 distinct 值,所以當 mysql 找到了第一條匹配的結果後,將停止該值的查詢而轉為後面其他值的查詢;

         Full scan on NULL key:子查詢中的一種優化方式,主要在遇到無法通過索引訪問 null值的使用使用;

         Impossible WHERE noticed after readingconsttables:MySQL Query Optimizer 通過收集到的統計資訊判斷出不可能存在結果;

         No tables:Query 語句中使用 FROMDUAL 或者不包含任何 FROM 子句;

         Not exists:在某些左連線中 MySQL QueryOptimizer 所通過改變原有 Query 的組成而使用的優化方法,可以部分減少資料訪問次數;

         Range checked for each record (indexmap: N):通過 MySQL 官方手冊的描述,當MySQL Query Optimizer 沒有發現好的可以使用的索引的時候,如果發現如果來自前面的表的列值已知,可能部分索引可以使用。對前面的表的每個行組合,MySQL檢查是否可以使用 range 或 index_merge 訪問方法來索取行。

         Select tablesoptimized away:當我們使用某些聚合函式來訪問存在索引的某個欄位的時候,MySQL Query Optimizer 會通過索引而直接一次定位到所需的資料行完成整個查詢。當然,前提是在 Query 中不能有 GROUP BY 操作。如使用 MIN()或者 MAX()的時候;  

         Using filesort:當我們的 Query 中包含 ORDER BY 操作,而且無法利用索引完成排序操作的時候,MySQL Query Optimizer 不得不選擇相應的排序演算法來實現。

         Using index:所需要的資料只需要在Index 即可全部獲得而不需要再到表中取資料;

         Using index forgroup-by:資料訪問和 Using index 一樣,所需資料只需要讀取索引即可,而當 Query 中使用了 GROUP BY 或者 DISTINCT 子句的時候,如果分組欄位也在索引中,Extra 中的資訊就會是 Using index for group-by;

         Using temporary:當 MySQL 在某些操作中必須使用臨時表的時候,在 Extra 資訊中就會出現 Using temporary 。主要常見於 GROUP BY 和 ORDER BY 等操作中。

         Using where:如果我們不是讀取表的所有資料,或者不是僅僅通過索引就可以獲取所有需要的資料,則會出現 Using where 資訊;

         Using where withpushed condition:這是一個僅僅在 NDBCluster 儲存引擎中才會出現的資訊,而且還需要通過開啟 Condition Pushdown 優化功能才可能會被使用。控制引數為 engine_condition_pushdown 。

相關文章