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
重點關注
id
,type
,possible_keys
,key
,Extra
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將被標記爲:DERIVEDUNION 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
的查詢