MySQL優化 - EXPLAIN

EXPLAIN是我們最常用的SQL分析工具,在使用工具之前我們需要先了解下工具中每一項代表的含義,如下是EXPLAIN中的所有列:

mysql> explain select * from user u1 left join user u2 on u1.id=u2.id where u1.name='wyh';
+----+-------------+-------+------------+--------+------------------+------------------+---------+----------------+------+----------+-------+
| id | select_type | table | partitions | type   | possible_keys    | key              | key_len | ref            | rows | filtered | Extra |
+----+-------------+-------+------------+--------+------------------+------------------+---------+----------------+------+----------+-------+
|  1 | SIMPLE      | u1    | NULL       | ref    | idx_name_address | idx_name_address | 1023    | const          |    1 |      100 | NULL  |
|  1 | SIMPLE      | u2    | NULL       | eq_ref | PRIMARY          | PRIMARY          | 8       | ssb_test.u1.id |    1 |      100 | NULL  |
+----+-------------+-------+------------+--------+------------------+------------------+---------+----------------+------+----------+-------+
2 rows in set

重點關注idtypepossible_keyskeyExtra

id

id表示執行順序:id越大越先執行,如果id相同則從上往下執行。

select_type

select_type表示查詢類型,主要用來區別普通查詢,子查詢,聯合查詢等。

  • SIMPLE: 簡單的 select 查詢,查詢中不包含子查詢或者UNION;
  • PRIMARY: 查詢中若包含任何複雜的子部分,最外層查詢則被標記爲;
  • SUBQUERY: 在SELECT或WHERE列表中包含了子查詢;
  • DERIVED: 在FROM列表中包含的子查詢被標記爲DERIVED(衍生),MySQL會遞歸執行這些子查詢, 把結果放在臨時表裏;
  • UNION: 若第二個SELECT出現在UNION之後,則被標記爲UNION;若UNION包含在FROM子句的子查詢中,外層SELECT將被標記爲:DERIVED
  • UNION RESULT: 從UNION表獲取結果的SELECT

table

表示這一行的數據是哪張表的。

type

type表示訪問類型,從好到壞依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

我們需要主要關注的是:system>const>eq_ref>ref>range>index>ALL

  • system:表只有一行記錄(等於系統表),這是const類型的特列;
  • const:表示通過索引一次就找到了;const用於比較主鍵或者唯一索引。因爲只匹配一行數據,所以很快,如將主鍵置於where列表中,MySQL就能將該查詢轉換爲一個常量;
  • eq_ref:表示只有一行數據與之匹配,通常是使用了主鍵索引或者唯一索引;
  • ref:表示使用了非唯一索引;
  • range:表示使用了索引來做範圍查詢
  • index:表示掃描了全部的索引,一般是用了索引來排序;
  • ALL:表示全表掃描;

possible_keys

possible_keys表示這次查詢可以用到的索引有哪些。

key

key表示優化器選中那個索引來執行這個查詢,如果要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

key_len

表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度。在不損失精確性的情況下,長度越短越好。

key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的。

ref

表示索引的哪一列被使用了,如果可能的話,是一個常數。哪些列或常量被用於查找索引列上的值。

rows

根據表統計信息及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數。

Extra

含不適合在其他列中顯示但十分重要的額外信息。

  • Using filesort:表示mysql會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中無法利用索引完成的排序操作稱爲“文件排序”。

  • Using temporary:表示使用了臨時表,常見於排序 order by 和分組查詢 group by。

  • Not exists:MYSQL優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行, 就不再搜索了。

  • Using index:表示使用了覆蓋索引。MySQL直接從索引中過濾不需要的記錄並返回命中的結果。這是MySQL服務層完成的,但無需再回表查詢記錄。

  • Using index condition:這是MySQL 5.6出來的新特性,叫做“索引條件推送”。簡單說一點就是MySQL原來在索引上是不能執行如like這樣的操作的,但是現在可以了,這樣減少了不必要的IO操作,但是隻能用在二級索引上。

  • Using where:使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。
    注意:Extra列出現Using where表示MySQL服務器將存儲引擎返回服務層以後再應用WHERE條件過濾。

  • Using join buffer:表示使用了連接緩存。

  • Impossible where:表示where子句的值總是false,不能用來獲取任何元組,比如在一個NOT NULL列上執行is null的查詢

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