MySQL EXPLAIN Output Format(MySQL運維神技)

摘要: DBA經常會用到的explain來查看SQL語句的執行計劃,今天小人斗膽,從MySQL 5.7 Reference Manual中把MySQL EXPLAIN Output Format翻譯過來。歡迎拍磚





Explain語句提供了一個select語句執行計劃的信息。

Explain爲每個用了select語句的表,返回一行信息。它列出了表中的順序輸出,MySQL會讀取他們,然後再處理。MySQL解決了所有使用嵌套循環連接方法。這意味着MySQL會讀取第一個表中的一行,然後在第二個表中找到一個匹配的行、第三個表,等等。當所有的表都被處理,MySQL輸出所選擇的列和回溯到的列表信息,直到發現有更多匹配行的表。下一行是從這個表中讀取的,這個過程將繼續同下一個表。

在MySQL 5.7.3之前,EXTENDED的關鍵詞還在被使用,explain產生的額外信息可以通過explain後面的show warnings解釋。EXPLAIN EXTENDED也顯示filtered列。在MySQL 5.7.3,擴展輸出默認開啓,擴展關鍵詞不再必要。

Note:
You cannot usethe EXTENDED and PARTITIONS keywords together in the same EXPLAIN statement. In addition, neither of these keywordscan be used together with the FORMAT option. (FORMAT=JSON causesEXPLAIN to display extended and partition informationautomatically; using FORMAT=TRADITIONAL has no effect on EXPLAIN output.)

 

EXPLAIN Output Columns

本部分主要描述explain所產生的輸出列,下部分提供了類型和額外的附加信息。Explain輸出的每一行都有關於表的信息。每一行都包含下表總結的值,explain輸出列,更詳細的描述。列名在表的第一列顯示;第二列提供了等效的屬性名稱,在輸出時顯示格式爲JSON的使用。

Table 9.1 EXPLAIN Output Columns

Column

JSON Name

Meaning

id

select_id

選擇標識符

select_type

None

選擇類型

table

table_name

輸出行的表

partitions

partitions

匹配的分區

type

access_type

連接類型

possible_keys

possible_keys

可能用到的索引

key

key

實際用到的索引

key_len

key_length

用到索引的長度

ref

ref

列對應的索引

rows

rows

預測要檢查的行數

filtered

filtered

表條件篩選行的百分比

Extra

None

額外的信息

id (JSON name: select_id)

選擇標識符。這是select請求的序列號。如果引用其他行的結果,這個值可 以爲null。在這種    情況下,表的列顯示的值類似<union M,N>,表示該行的值在M和N之間。

select_type (JSON name: none)

選擇的類型,它可以是下表中的任何一種。一個explain JSON-formatted顯示了作爲一個query_block屬性時的SELECT類型,除非它是簡單或主鍵。JSON的名稱(如適用)也在表中顯示。

 

select_type Value

JSON Name

Meaning

SIMPLE

None

簡單查詢(沒有union和子查詢)

PRIMARY

None

最外層查詢

UNION

None

第二層,在select之後使用union

DEPENDENT UNION

dependent (true)

 union 語句中的第二個select,依賴於外部子查詢

UNION RESULT

union_result

從一個union返回結果

SUBQUERY

None

子查詢中的第一個select

DEPENDENT SUBQUERY

dependent (true)

子查詢中的第一個select依賴於外部子查詢

DERIVED

None

派生表 select(from子句中的子查詢)

MATERIALIZED

materialized_from_subquery

物化子查詢(具體化)

UNCACHEABLE SUBQUERY

cacheable (false)

子查詢的結果不能被緩存,必須重新評估每行的外部查詢

UNCACHEABLE UNION

cacheable (false)

union中的第二個或後面的select   屬於UNCACHEABLE SUBQUERY

DEPENDENT SUBQUERY 不等價與 UNCACHEABLE SUBQUERY。相關子查詢,子查詢根據每組不同的值和不同的外部語境只會重新估值一次。不可緩存子查詢,子查詢根據每行不同的外部語境估值。.

可緩存的子查詢不同於緩存查詢的結果。查詢緩存發生在子查詢完成時,而查詢緩存用於存儲查詢執行完成後的結果。

當使用explain時指定FORMAT=JSON,沒有直接的輸出等同於select_type,此時等同於把query_block的屬性賦予SELECT。性能相當於大部分子查詢類型只顯示可用(例如 materialized_from_subquery for MATERIALIZED)並在適當的時候顯示可用。沒有JSON等價SIMPLE or PRIMARY.

在MySQL 5.7.2,select_type 等值non-SELECT 語句,顯示受影響表的語句類型。For example, select_type is DELETE for DELETE statements。

 

table (JSON name: table_name)

輸出引用行的表的名字,也可能是以下幾種情況

<unionM,N>: 這行指的是聯合查詢中id值在M和N之間的行。

<derivedN>: 這行指出派生表結果集在這行中的id值爲N。A derived table  may result, for example, from a subqueryin the FROM clause.

<subqueryN>: 該行指的是物化查詢在這行的ID值爲N。

SeeSection 9.2.1.18.2,“Optimizing Subqueries with Subquery Materialization”.

 

partitions (JSON name: partitions)

查詢匹配的記錄分區,只有在分區關鍵詞被使用時,這列纔會顯示。未分區的表值爲空。See Section 20.3.5,“Obtaining Information About Partitions”.

 

type (JSON name: access_type)

連接類型。描述不同的類型, see EXPLAIN JoinTypes

 

possible_keys (JSON name: possible_keys)

可能的索引列標識,哪個索引MySQL可能選擇找到此表中的行。請注意,這列完全獨立於explain輸出裏列表。這意味着一些關鍵詞在 possible_keys裏面可能不會被實際應用到。 

如果這列爲null(或者沒有在JSON-formatted輸出定義),沒有相關的索引。在這種情況下,你可以提升你的請求性能,檢查where子句是否引用了一些列或列,適用於索引。如果是這樣的話,創建一個合適的索引,然後再用explain檢查一遍query。SeeSection 14.1.8, “ALTER TABLE Syntax”.

看錶都有什麼索引,用SHOW INDEXFROM tbl_name.

 

key (JSON name: key)

key這列標明瞭MySQL真實用到的索引。如果MySQL決定使用possible_keys 裏面的索引去遍歷行,這個索引作爲key的值被列出。

key的值也可能不在 possible_keys 裏。如果possible_keys裏的索引都不適合遍歷行,那麼所有被查詢的列會用其他索引。也就是說,查詢的列用到了索引,即使它沒有被用來決定檢索哪些行,索引掃描也比直接掃描數據有效果。在InnoDB引擎下,即使請求查詢主鍵列也可能用到二級索引,因爲InnoDB在每一個二級索引裏存儲主鍵值。如果key 是空的,MySQL發現沒有索引用來提高查詢效率。

強制MySQL去使用或忽略一個在 possible_keys 列的索引, 使用FORCEINDEX, USE INDEX, or IGNORE INDEX in your query. See Section 9.9.4,“Index Hints”.

對於MyISAM 表, 使用 ANALYZE TABLE 幫助優化選擇更好的索引。 For MyISAM tables, myisamchk--analyze doesthe same. See Section 14.7.2.1, “ANALYZE TABLE Syntax”, and Section 8.6,“MyISAM Table Maintenance and Crash Recovery”.

 

key_len (JSON name: key_length)

key_len 這列顯示的MySQL使用索引的長度。key_len的值可以讓你決定MySQL使用前綴索引的長度。如果key列是null, len_len 列也是 NULL。

由於索引的存儲格式,一個null列索引長度可能比not null更大。

 

ref (JSON name: ref)

ref 列顯示哪列或常量常被用來和key配合從表中查出數據。

如果值是 func,它的值是一些函數的結果。去看是哪個函數,使用 EXPLAIN EXTENDED 然後SHOW WARNINGS。函數實際上可能是一個運算符,如算術運算符。

 

rows (JSON name: rows)

rows 列顯示MySQL查詢請求必須檢查的行數。

對於 InnoDB 表, 這個數字是個約數,並不能總是很精確。

 

filtered (JSON name: filtered)

filtered 列顯示錶行的估計百分比。rows顯示檢查的預計行數,rows × filtered / 100 顯示之前連接那個表的行數。在MySQL 5.7.3以前,如果你使用 EXPLAIN EXTENDED,這列會顯示。到了MySQL 5.7.3,擴展輸出默認開啓,擴展關鍵詞也不是必須的。

 

Extra (JSON name: none)

這列包含關於MySQL如何解決查詢問題的更多信息。對於不同值得描述,請看EXPLAIN Extra Information.

沒有簡單的JSON 格式對應 Extra 列;然而,當列表JSON特性或者消息屬性的本質,會有值。

 

EXPLAIN Join Types

Type這列顯示的是表連接類型。下面描述的連接類型,默認從最優到最差。

 

system

這個表只有一行數據(= system table). 這是const連接類型的一個特例。

 

const

這個表至少有一行匹配,在查詢開始時讀。因爲只有一行,這行中的列值可以被優化器當作常數。Const表非常快,因爲只讀一次。

當主鍵或聯合索引的所有部分和常量比較時,會用到const。

const is used when you compare all parts of a PRIMARYKEY or UNIQUE 

index to constant values. In the following queries,tbl_name canbe used as a const table:

 640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

 

eq_ref

先前表中的每一行在這個表中只能找到一行。除了system和const連接類型,這是最可能的連接類型。連接時,主鍵或唯一非null索引全部使用時會使用此類型。

eq_ref可以被用在索引列進行“=”號操作符比較時。比較值可以是一個常量或者在這個表之前讀取的表中的列的表達式。

The following examples, MySQL can use an eq_ref join to process ref_table

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

 

ref

先前表中的所有行索引匹配值都從這個表中讀取。如果連接只用到了最左前  綴索引或者索引不是主鍵或者唯一索引(換句話說,連接不能基於鍵值選擇簡單的一行)使用到ref類型。如果索引只是被用來匹配幾行,這是一個好的連接型    

ref can be usedfor indexed columns that are compared using the = or <=> 

operator. In the following examples, MySQL can use a ref join to process ref_table:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

 

fulltext

全文索引會用到這個鏈接類型。

 

ref_or_null

這個連接類型和ref很像,做爲補充,MySQL爲包含NULL值得行做了其他查詢。這種連接類型最常用來解決子查詢。

In thefollowing examples, MySQL can use a ref_or_null join to process ref_table:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

See Section 9.2.1.8, “IS NULLOptimization”.

 

index_merge

此連接類型表示使用索引合併優化。在這種情況下,輸出的索引列包含使用的索引的列表,key_len顯示所用索引的最大部分。

For moreinformation, seeSection 9.2.1.4, “Index MergeOptimization”.

 

unique_subquery

This typereplaces eq_ref forsome IN subqueriesof the following form:

value IN (SELECT primary_key FROM single_table WHERE some_expr)

Unique_subquery .只是一個索引查找函數來替代子查詢獲得更好的性能。

 

index_subquery

這種連接類型類似unique_subquery。它替代in 類型子查詢,但是它在非唯一索引的子查詢中起作用。

It replaces IN subqueries,but it works for nonunique indexes in subqueries of the following form:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

 

range

只有在給定範圍的行中被檢索,使用索引查詢這些行。再輸出的索引列中指明哪個索引被使用。Key_len包含被使用的最大索引長度。這種類型ref列爲null。

Range can beused when a key column is compared to a constant using any of the =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, or IN() operators:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

 

index

這種連接類型和all一樣,除了掃描索引樹。發生在下面兩種情況:        

1、如果對於查詢索引是一個覆蓋索引並且可以滿足這個表所有數據的查詢,只是掃描索引樹。這種情況下, Extra 列顯示 Using index。index-only類型掃描通常比 ALL類型快,因爲索引的大小通常比表數據小。

2、全表掃描利用索引來查找數據行中的索引。Uses index 不出現Extra 列。

當查詢索引列的部分時,MySQL 可以使用這種類型。

 

ALL

全表掃描,性能很差。通常可以添加索引來避免這種情況

A fulltable scan is done for each combination of rows from the previous 

tables. This is normally not good if the table is the first table not   marked const, andusually very bad in all other cases. Normally, you canavoid ALL by addingindexes that enable row retrieval from the table based on constant values orcolumn values from earlier tables.

 

EXPLAIN Extra Information

Extra 列是 EXPLAIN 輸出的額外信息關於MySQL 解析查詢。下面的信息是可能出現在這列的值。每個項目還包含了JSON-formatted 輸出信息顯示的附加值。對於其中的一些,它是一個特定的屬性。其他顯示消息屬性文本。

如果你想讓你的查詢儘可能的快,查看 Extra 列的值是否是 Using filesort and Using temporary, 或者 JSON-formatted EXPLAIN output, using_filesort 和 using_temporary_table基本等價。

 

Child of 'table' pushed join@1 (JSON: message text)

This tableis referenced as the child of table in a join that can be pushed down to the NDBkernel. Applies only in MySQL Cluster, when pushed-down joins are enabled. Seethe description of the ndb_join_pushdown serversystem variable for more information and examples.

 

const row not found (JSON property: const_row_not_found)

For aquery such as SELECT ... FROM tbl_name,the table was empty.

 

Deleting all rows (JSON property: message)

For DELETE, some storage engines (such as MyISAM) support a handler methodthat removes all table rows in a simple and fast way. This Extra valueis displayed if the engine uses this optimization.

 

Distinct (JSON property: distinct)

MySQL 查詢不同的值,當它發現第一個匹配的行時停止查找。

 

FirstMatch(tbl_name) (JSON property: first_match)

Thesemi-join FirstMatch join shortcutting strategy is used for tbl_name.

 

Full scan on NULL key (JSON property: message)

This occurs for subquery optimization as afallback strategy when the optimizer cannot use an index-lookup access method.

 

Impossible HAVING (JSON property: message)

HAVING 字句經常錯誤不能查詢任何行。

 

Impossible WHERE (JSON property: message)

The WHERE clauseis always false and cannot select any rows.

 

Impossible WHERE noticed after reading const tables (JSONproperty: message)

MySQL hasread all const (and system) tables andnotice that the WHERE clause is always false.

 

Loose Scan(m..n) (JSON property: message)

Thesemi-join LooseScan strategy is used. m and n are key part numbers.

 

No matching min/max row (JSON property: message)

No rowsatisfies the condition for a query such as SELECTMIN(...) FROM ... WHERE condition.

 

no matching row in const table (JSON property: message)

For a query with a join, there was an emptytable or a table with no rows satisfying a unique index condition.

 

No matching rows after partition pruning (JSONproperty: message)

For DELETE or UPDATE, the optimizer found nothing to delete or updateafter partition pruning. It is similar in meaning to Impossible WHERE for SELECT statements.

 

No tables used (JSON property: message)

The queryhas no FROM clause,or has a FROM DUAL clause.

For INSERT or REPLACE statements, EXPLAIN displays this value when there is no SELECT part. For example, it appears forEXPLAIN INSERT INTO t VALUES(10) because that is equivalent to EXPLAIN INSERT INTO t SELECT 10 FROM DUAL.

 

Not exists (JSON property: message)

MySQL wasable to do a LEFT JOIN optimization on the query and does not examine morerows in this table for the previous row combination after it finds one row thatmatches the LEFT JOIN criteria. Here is an example of the type of querythat can be optimized this way:

Assumethat t2.id is defined as NOT NULL. In this case, MySQL scans t1 and looks up the rows in t2 usingthe values oft1.id. If MySQL finds a matching row in t2, it knowsthat t2.id can never be NULL, and does not scan through the rest of the rows in t2 thathave the same id value.In other words, for each row in t1, MySQL needs to do only a single lookup in t2,regardless of how many rows actually match in t2.

 

Plan isn't ready yet (JSON property: none)

This valueoccurs with EXPLAIN FOR CONNECTION whenthe optimizer has not finished creating the execution plan for the statementexecuting in the named connection. If execution plan output comprises multiplelines, any or all of them could have this Extra value, depending on the progress of the optimizerin determining the full execution plan.

 

Range checked for each record (index map: N) (JSONproperty: message)

MySQLfound no good index to use, but found that some of indexes might be used aftercolumn values from preceding tables are known. For each row combination in thepreceding tables, MySQL checks whether it is possible to use a range orindex_merge accessmethod to retrieve rows. This is not very fast, but is faster than performing ajoin with no index at all. The applicability criteria are as described in Section 9.2.1.3, “Range Optimization”,and Section 9.2.1.4, “Index MergeOptimization”, with the exception that all column values for thepreceding table are known and considered to be constants.

Indexesare numbered beginning with 1, in the same order as shown by SHOW INDEX for the table. Theindex map value N is a bitmask value that indicates which indexes arecandidates. For example, a value of 0x19 (binary 11001) means that indexes 1, 4, and 5 willbe considered.

 

Scanned N databases (JSON property: message)

Thisindicates how many directory scans the server performs when processing a queryfor INFORMATION_SCHEMA tables, as described in Section 9.2.4,“Optimizing INFORMATION_SCHEMA Queries”. The value of N canbe 0, 1, or all.

 

Select tables optimized away (JSON property: message)

The optimizer determined 1) that at mostone row should be returned, and 2) that to produce this row, a deterministicset of rows must be read. When the rows to be read can be read during theoptimization phase (for example, by reading index rows), there is no need toread any tables during query execution.

The firstcondition is fulfilled when the query is implicitly grouped (contains anaggregate function but no GROUP BY clause). The second condition is fulfilled when onerow lookup is performed per index used. The number of indexes read determinesthe number of rows to read.

Consider the following implicitly groupedquery:111027_05nT_3023401.pngSupposethat MIN(c1) can be retrieved by reading one index row and MIN(c2) canbe retrieved by reading one row from a different index. That is, for eachcolumn c1 and c2, thereexists an index where the column is the first column of the index. In thiscase, one row is returned, produced by reading two deterministic rows.

This Extra valuedoes not occur if the rows to read are not deterministic. Consider this query:    111027_XicT_3023401.png

Supposethat (c1, c2) is a covering index. Using this index, all rowswith c1 <= 10 must be scanned to find the minimumc2 value.By contrast, consider this query:111027_r7aE_3023401.png

In thiscase, the first index row with c1 = 10 contains the minimum c2 value. Only one row must be read to produce thereturned row.

Forstorage engines that maintain an exact row count per table (such as MyISAM, butnot InnoDB), this Extra value can occur for COUNT(*) queries for which the WHERE clause is missing or always true and there isno GROUP BY clause. (This is an instance of an implicitlygrouped query where the storage engine influences whether a deterministicnumber of rows can be read.)

 

Skip_open_table, Open_frm_only, Open_full_table (JSONproperty: message)

Thesevalues indicate file-opening optimizations that apply to queries for INFORMATION_SCHEMA tables, as described inSection 9.2.4,“Optimizing INFORMATION_SCHEMA Queries”.

1、Skip_open_table:Table files do not need to be opened. The information has already becomeavailable within the query by scanning the database directory.

2、Open_frm_only:Only the table's .frm file need be opened.

3、Open_full_table:The unoptimized information lookup. The .frm, .MYD, and .MYI files must be opened.

 

Start temporary, End temporary (JSONproperty: message)

This indicates temporary table use for thesemi-join Duplicate Weedout strategy.

 

unique row not found (JSON property: message)

For aquery such as SELECT ... FROM tbl_name,no rows satisfy the condition for a UNIQUE index or PRIMARYKEY on the table.

 

Using filesort (JSON property: using_filesort)

MySQL 需要做一個額外的排序去查找如何檢索排序中的行。排序通過所有行的連接類型和索引的存儲順序和指向行的指針去匹配where字句。索引排序然後根據排序檢索行。See Section 9.2.1.15, “ORDER BYOptimization”.

 

Using index (JSON property: using_index)

從表中讀取列信息僅僅使用索引樹中的信息,沒有必須額外去回表。這個策略可以被使用在查詢僅使用了索引列的一部分。

InnoDB 表有一個自定義的聚集索引,即使 Extra列沒有Usingindex也會被使用。如果 type is index and key is PRIMARY,發生這種情況。

 

Using index condition (JSON property: using_index_condition)

Tables areread by accessing index tuples and testing them first to determine whether toread full table rows. In this way, index information is used to defer (“push down”) reading full table rows unless it is necessary.See Section 9.2.1.6,“Index Condition Pushdown Optimization”.

IndexCondition Pushdown (ICP)是MySQL 5.6版本中的新特性,是一種在存儲引擎層使用索引過濾數據的一種優化方式。

1、當關閉ICP時,index 僅僅是data access 的一種訪問方式,存儲引擎通過索引回表獲取的數據會傳遞到MySQL Server層進行where條件過濾。

2、當打開ICP時,如果部分where條件能使用索引中的字段,MySQL Server會把這部分下推到引擎層,可以利用index過濾的where條件在存儲引擎層進行數據過濾,而非將所有通過index access的結果傳遞到MySQL server層進行where過濾。

優化效果:ICP能減少引擎層訪問基表的次數和MySQL Server訪問存儲引擎的次數,減少IO次數,提高查詢語句性能。

 

Using index for group-by (JSON property: using_index_for_group_by)

類似使用索引訪問表的方法, Using index for group-by 表明MySQL 發現一個索引可以被用來檢索所有列關於GROUP BY or DISTINCT 查詢,沒有任何額外的訪問磁盤迴表。此外,這個索引被使用最有效的方式對每個group,只有幾個索引被讀取。

Fordetails, seeSection 9.2.1.16, “GROUP BYOptimization”.

 

Using join buffer (Block Nested Loop), Using joinbuffer (Batched Key Access) (JSON property:using_join_buffer)

將join前面的表的一部分放到join buffer中,然後用buffer中的記錄跟當前表執行join操作。(Block Nested Loop) 表示使用Block Nested-Loop算法,(Batched Key Access) 表示使用Batched Key Access算法。就是說,前面的key列中出現的字段會放到join buffer中,然後從出現 Using join buffer 的那一行table字段列出的表中分批取回匹配的行。

InJSON-formatted output, the value of using_join_buffer is always either one of Block Nested Loop or BatchedKey Access.

 

Using MRR (JSON property: message)

Tables areread using the Multi-Range Read optimization strategy. See Section 9.2.1.13, “Multi-RangeRead Optimization”.

 

Using sort_union(...), Using union(...), Usingintersect(...) (JSON property: message)

Theseindicate how index scans are merged for the index_merge jointype. See Section 9.2.1.4, “Index MergeOptimization”.

 

Using temporary (JSON property: using_temporary_table)

爲了處理查詢,需要創建臨時表保存結果。如果查詢語句包含GROUP BY和ORDER BY並且列出的字段不一樣,Extra會出現此信息。

 

Using where (JSON property: attached_condition)

WHERE子句用於限制返回給客戶端或與下一個表匹配的記錄。除非你確實想要獲取或檢查表的所有行,否則查詢會有問題,若Extra不包含Using where並且連接類型爲ALL或index。

Using where has no direct counterpart in JSON-formatted output;the attached_condition property contains any WHEREcondition used.

 

Using where with pushed condition (JSONproperty: message)

This itemapplies to NDB tables only. It meansthat MySQL Cluster is using the Condition Pushdown optimization to improve theefficiency of a direct comparison between a nonindexed column and a constant.In such cases, the condition is “pushed down” tothe cluster's data nodes and is evaluated on all data nodes simultaneously.This eliminates the need to send nonmatching rows over the network, and canspeed up such queries by a factor of 5 to 10 times over cases where ConditionPushdown could be but is not used. For more information, see Section 9.2.1.5,“Engine Condition Pushdown Optimization”.

 

Zero limit (JSON property: message)

The queryhad a LIMIT 0 clause and cannot select any rows.

爲了方便大家交流,本人開通了微信公衆號,和QQ羣291519319。喜歡我的一起來交流吧


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