1、explain輸出列
mysql> explain select tm.* from ((select * from t1) union (select * from t2) union (select * from t3
)) tm;
+------+--------------+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+------+--------------+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 6 | 100 | NULL |
| 2 | DERIVED | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100 | NULL |
| 3 | UNION | t2 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100 | NULL |
| 4 | UNION | t3 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100 | NULL |
| NULL | UNION RESULT | <union2,3,4> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+------+--------------+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
id
包含一組數字,表示查詢中執行select子句的或者操作表的順序,
id相同,執行順序由上至下順序執行
id不同,id值越大優先級越高,越先執行
id相同或者不同,如果相同,可以認爲是一組,從上往下順序執行;在所有組中,id值越大,優先級越高,越先執行
id值可能爲null,表示最後的結果集來源於union的結果,在這種情況下,使用一個類似<unionM,N>來表示這些行指向的是id爲M和N的union結果集
select_type
select的子句類型,一般爲以下幾種
select_type值 | json 命名 | 含義 |
---|---|---|
SIMPLE | None | 簡單select類型,不使用union和子查詢的 |
PRIMARY | None | 查詢中包任何複雜的子部分的最外層查詢 |
UNION |
None | union子句中的第二個或者往後的select |
DEPENDENT UNION | dependent (true ) |
依賴於外部查詢的第二個或者往後的union select |
UNION RESULT | union_result | union子句的結果 |
SUBQUERY |
None | 子查詢中的第一個select |
DEPENDENT SUBQUERY | dependent (true ) |
依賴於外部查詢的子查詢中的第一個select |
DERIVED | None | 衍生表 |
DEPENDENT DERIVED | dependent (true ) |
表示依賴於另外表的衍生表 |
MATERIALIZED | materialized_from_subquery | 物化子查詢 |
UNCACHEABLE SUBQUERY | cacheable (false ) |
表示該子查詢的結果集將不會被緩存並且一定會被外部查詢重新計算 |
UNCACHEABLE UNION | cacheable (false ) |
屬於uncacheable subquery的第二個或者往後的union select |
table
表示結果集中的行指向的表,一般有以下幾種
- <unionM,N>:id爲M和N的結果集的union
- :結果集的行來源於衍生表的結果集,N表示來源於select標識符爲N的select
- :物化子查詢N的結果集
- 表名
partitions
表示將會被該查詢匹配的分區,其值爲空表示表不可分區
type
表示mysql在表中找到所需行的方式,一般有以下幾種
system
表只有一行數據,const的特例
const
表示該表只有一行匹配的數據,比如主鍵和唯一鍵的查詢方式,速度僅次於system
eq_ref
對於每個索引鍵值,表中只有一條記錄匹配,簡單來說,就是多表連接中使用primary key或者 unique key作爲關聯條件
ref
表示所有行都匹配索引值,表中有多行記錄匹配
ref
使用非唯一索引掃描或者唯一索引的前綴掃描,返回匹配某個單獨值的記錄行
fulltext
全文索引
ref_or_null
在ref的基礎上,但是使用了一個額外的空值匹配
SELECT \* FROM *ref\_table* WHERE *key\_column*\=*expr* OR *key\_column* IS NULL;
index_merge
表示索引合併優化。In this case, thekey
column in the output row contains a list of indexes used, andkey_len
contains a list of the longest key parts for the indexes used
unique_subquery
表示下面使用在子查詢中的eq_ref,比如下面形式:
*value* IN (SELECT *primary\_key* FROM *single\_table* WHERE *some\_expr*)
unique_subquery
僅僅是一種完全爲了更好查詢效率的一種索引查找功能
range
索引範圍掃描,對索引的掃描開始於某一點,返回匹配值域的行。顯而易見的索引範圍掃描是帶有between或者where子句裏帶有查詢。當mysql使用索引去查找一系列值時,例如IN()和OR列表,也會顯示range(範圍掃描),當然性能上面是有差異的。
index
和ALL一樣,只是這裏掃描的是索引樹,而不是物理表
- 當查詢結果集只需要掃描索引樹就可滿足要求,則Extra列出現Using Index。其實就是索引覆蓋,這種事比ALL快很多的,畢竟索引很快
- 沒有使用到索引覆蓋,而是按照索引順序來掃描全表,Using index不會出現在Extra列
ALL
全表掃描
possible_keys
表示mysql可以用來查找該表中記錄的索引,查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢使用
key
表示真正被使用於查詢的索引key
ForInnoDB
, a secondary index might cover the selected columns even if the query also selects the primary key becauseInnoDB
stores the primary key value with each secondary index. Ifkey
isNULL
, MySQL found no index to use for executing the query more efficiently.
To force MySQL to use or ignore an index listed in thepossible_keys
column, useFORCE INDEX
,USE INDEX
, orIGNORE INDEX
in your query. SeeSection 8.9.4, “Index Hints”.
ForMyISAM
tables, runningANALYZE TABLE
helps the optimizer choose better indexes. ForMyISAM
tables,myisamchk --analyzedoes the same. SeeSection 13.7.3.1, “ANALYZE TABLE Syntax”, andSection 7.6, “MyISAM Table Maintenance and Crash Recovery”.
key_len
表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度(key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的
ref
表示上述表的連接匹配條件,即哪些列或常量被用於查找索引列上的值
rows
表示MySQL根據表統計信息及索引選用情況,估算的找到所需的記錄所需要讀取的行數
filtered
表示預計通過表條件過濾掉的錶行百分比,rowsfiltered表示將要被用於接下來的連接的行數,比如,rows=1000,filtered=50%,那麼用戶連接另一個表的行數爲1000filtered=500
Extra
包含不適合在其他列中顯示但十分重要的額外信息
- Using index:該值表示相應的select操作中使用了覆蓋(Covering Index)
- Using where:表示mysql服務器將在存儲引擎檢索行後再進行過濾。許多where條件裏涉及索引中的列,當(並且如果)它讀取索引時,就能被存儲引擎檢驗,因此不是所有帶where字句的查詢都會顯示"Using where"。有時"Using where"的出現就是一個暗示:查詢可受益與不同的索引。
- Using temporary:表示MySQL需要使用臨時表來存儲結果集,常見於排序和分組查詢。這個值表示使用了內部臨時(基於內存的)表。一個查詢可能用到多個臨時表。有很多原因都會導致MySQL在執行查詢期間創建臨時表。兩個常見的原因是在來自不同表的上使用了DISTINCT,或者使用了不同的ORDER BY和GROUP BY列。可以強制指定一個臨時表使用基於磁盤的MyISAM存儲引擎。這樣做的原因主要有兩個
1)內部臨時表佔用的空間超過min(tmp_table_size,max_heap_table_size)系統變量的限制
2)使用了TEXT/BLOB 列 - Using filesort:MySQL中無法利用索引完成的排序操作稱爲“文件排序”
- Using join buffer:強調了在獲取連接條件時沒有使用索引,並且需要連接緩衝區來存儲中間結果。如果出現了這個值,那應該注意,根據查詢的具體情況可能需要添加索引來改進能。
- Impossible where:這個值強調了where語句會導致沒有符合條件的行
- Select tables optimized a way:這個值意味着僅通過使用索引,優化器可能僅從聚合函數結果中返回一行.
- Index merges:當MySQL 決定要在一個給定的表上使用超過一個索引的時候,就會出現以下格式中的一個,詳細說明使用的索引以及合併的類型。Using sort_union(…),Using union(…),Using intersect(…)
總結:
• EXPLAIN不會告訴你關於觸發器、存儲過程的信息或用戶自定義函數對查詢的影響情況
• EXPLAIN不考慮各種Cache
• EXPLAIN不能顯示MySQL在執行查詢時所作的優化工作
• 部分統計信息是估算的,並非精確值
• EXPALIN只能解釋SELECT操作,其他操作要重寫爲SELECT後查看執行計劃。**