mysql 執行計劃EXPLAIN 解析

  • EXPLAIN   用來查看sql的執行計劃,其中每個字段的具體含義什麼?有哪些值?可以如何幫助我們進行sql優化呢?
  • 先來看一個示例:name 上建立了索引。
    EXPLAIN select name from t_user A where name='rr';
     

  • 先來看下官方的文檔解釋:5地址 https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
  • 官方文檔:
    Column JSON Name Meaning(釋義)
    id select_id The SELECT identifier   select標識id
    select_type None The SELECT type  select 類型
    table table_name The table for the output row 輸出行表
    partitions partitions The matching partitions 匹配的分區
    type access_type The join type  連接類型
    possible_keys possible_keys The possible indexes to choose 可能選擇的索引
    key key The index actually chosen 實際選擇的索引
    key_len key_length The length of the chosen key  選擇鍵的長度
    ref ref The columns compared to the index 與索引比較的列
    rows rows Estimate of rows to be examined  預估檢查的行數
    filtered filtered Percentage of rows filtered by table condition 按表條件過濾的行百分比
    Extra None Additional information 額外的信息
  • Erxtra 具體值的意思分析;   
  • Using index:   僅使用索引樹中的信息從表中檢索列信息,而不必進行其他查找以讀取實際行。 對於使用InnoDb表而言,由於主鍵聚集索引的特性,在extra 列沒有看到 Using index 也可能會使用 主鍵索引。
  • Using index condition :測試是否需要讀取完整的行記錄,需要則根據索引下推到存儲引擎進行過濾。
  • Using where : 用來限制下一個表匹配的行或者返回客戶端的行。表明在索引樹中(不包含聚集索引的葉子節點,該葉子節點是存儲實際的行記錄的)無法找到需要的所有列。
  • using where &using index :使用到索引,需要回表查詢。
  • 聚集索引: Innodb 存儲引擎裏每個表都有一個默認的或者設置的主鍵索引,用來構建一棵樹,樹的葉子節點來保存表記錄。葉子節點通過指針連接。
  • 索引優化點: 避免回表查詢
  • 查詢語句:
    EXPLAIN select name,pass_word from t_user A where name='rr'  and pass_word='ss' and is_del=0;
    
  • 結果:
  • 分析:(name,pass_word,is_del)建立了一個聯合索引,查詢的列爲name,pass_word 都屬於聯合索引列,且查詢條件 也是使用到了聯合索引,故不需要回表查詢,在聯合索引樹上即可得到需要的數據。這也是using_index的意思。
  • 下面查詢語句改爲
    EXPLAIN select * from t_user A where name='rr'  and pass_word='ss' and is_del=0;
    

     

  • 分析: 可見也用到了索引,但是extra信息爲空。這表明需要回表查詢。查詢出所有列。
  • 我們再來看一下 1(name,index)查詢的分析:
  • 
    EXPLAIN select * from t_user A where name='rr'   and is_del=0;
    

     

  • 結果;

  • 繼續看: 2(name,pass_word)

    EXPLAIN select * from t_user A where name='rr'  and pass_word='ss';
    

     

  • 結果:

  • 分析: 從結果上看:都用到了索引,但是   1的extra信息爲 Using index condition 2 爲空。2 的ref 爲const,const  1 爲const。這可以說明一些問題: 即 2通過索引直接找到查詢的數據。1 通過索引查詢到數據後,進行了一次索引下推的過濾操作。

  • 那麼我們可以推斷下兩種執行情況: 2 通過聯合索引直接找到了符合條件的所有葉子節點信息,葉子節點存儲了主鍵的值,再通過主鍵值在主鍵的聚集索引上查找到需要的記錄,則完成此次查詢。

  • 1 通過聯合索引找到所有符合a的葉子節點,在通過葉子節點的主鍵值查詢到所有記錄,然後在得到的所有記錄裏通過條件is_del=0 過濾記錄,然後返回。

  • 可見 a c 情況下的效率是低於ab,abc,a.

  • 我們再來看 a.b,c 單獨建立索引的情況。

  • 執行語句:

    EXPLAIN select * from t_login_user A where user_name='rr'  and user_pwd='ss' and is_del=0;
    

     

  • 結果:

  • 分析: 三列 user_name  user_pwd  is_del  都建立了單獨的索引,但是隻是用到了name的索引,using where也代表了使用了回表查詢。

  • 執行語句:

    EXPLAIN select * from t_login_user A where user_name='rr'   and is_del=0;
    

     

  • 結果:

  • 分析:也只是用到了name索引。

  • 在高性能mysql書裏提到,mysql會合並這種單列的索引,這裏合併索引的話是通過參數optimizer_switch來控制的。

  • 我的mysql版本5.7.10 .  分析結果是沒有合併索引,這點有待進一步思考分析。???

 

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章