MySQL-EXPLAIN执行计划Extra解释
EXPLAIN命令输出的列中Extra字段可选值较多,这里单独说一下。
该Extra
列 EXPLAIN
输出包含MySQL解决查询的额外信息。以下列表说明了此列中可能出现的值。每个项目还指示JSON格式的输出哪个属性显示Extra
值。对于其中一些,有一个特定的属性。其他显示为message
属性的文本。
如果你想使你的查询尽可能快,看出来Extra
的列值Using filesort
和Using temporary
,或在JSON格式的EXPLAIN
输出,用于 using_filesort
和 using_temporary_table
等于性能 true
。
-
Child of '
(JSON:table
' pushed join@1message
文字)此表被引用为
table
可以下推到NDB内核的联接中的子代 。仅当启用了下推式联接时,才适用于NDB群集。有关ndb_join_pushdown
更多信息和示例,请参阅 服务器系统变量的说明。 -
const row not found
(JSON属性:const_row_not_found
)对于诸如此类的查询,该表为空。
SELECT ... FROM
tbl_name
-
Deleting all rows
(JSON属性:message
)因为
DELETE
,某些存储引擎(例如MyISAM
)支持一种处理程序方法,该方法以简单快捷的方式删除所有表行。Extra
如果引擎使用此优化,则会显示此值。 -
Distinct
(JSON属性:distinct
)MySQL正在寻找不同的值,因此它在找到第一个匹配行后停止为当前行组合搜索更多行。
-
FirstMatch(
(JSON属性:tbl_name
)first_match
)semijoin FirstMatch连接快捷方式用于
tbl_name
。 -
Full scan on NULL key
(JSON属性:message
)当优化程序无法使用索引查找访问方法时,子查询优化会作为回退策略发生这种情况。
-
Impossible HAVING
(JSON属性:message
)该
HAVING
子句始终为false,不能选择任何行。 -
Impossible WHERE
(JSON属性:message
)该
WHERE
子句始终为false,不能选择任何行。 -
Impossible WHERE noticed after reading const tables
(JSON属性:message
) -
LooseScan(
(JSON属性:m
..n
)message
)使用半连接LooseScan策略。
m
并且n
是关键部件号。 -
No matching min/max row
(JSON属性:message
)没有行满足查询的条件,例如 。
SELECT MIN(...) FROM ... WHERE
condition
-
no matching row in const table
(JSON属性:message
)对于具有连接的查询,有一个空表或没有满足唯一索引条件的行的表。
-
No matching rows after partition pruning
(JSON属性:message
)对于
DELETE
或UPDATE
,优化器在分区修剪后没有发现任何删除或更新的内容。这是在意义上类似Impossible WHERE
的SELECT
声明。 -
No tables used
(JSON属性:message
)查询没有
FROM
子句,或者有FROM DUAL
子句。对于
INSERT
或REPLACE
语句,EXPLAIN
在没有SELECT
部分时显示该值。例如,它似乎EXPLAIN INSERT INTO t VALUES(10)
因为相当于EXPLAIN INSERT INTO t SELECT 10 FROM DUAL
。 -
Not exists
(JSON属性:message
)MySQL能够对
LEFT JOIN
查询进行优化,并且在找到与LEFT JOIN
标准匹配的行之后,不会检查此表中更多行以用于上一行组合。以下是可以通过以下方式优化的查询类型的示例:SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.id IS NULL;
假设
t2.id
定义为NOT NULL
。在这种情况下,MySQL 使用的值 扫描t1
并查找行 。如果MySQL找到匹配的行 ,则它知道 永远不会 ,并且不会扫描具有相同值的其余行。换句话说,对于每一行,MySQL只需要进行一次查找,而不管实际匹配的行数。t2
t1.id
t2
t2.id
NULL
t2
id
t1
t2
t2
-
Plan isn't ready yet
(JSON属性:无)EXPLAIN FOR CONNECTION
当优化程序尚未完成为在命名连接中执行的语句创建执行计划时, 会出现此值。如果执行计划输出包含多行,则它们中的任何一个或全部都可以具有此Extra
值,具体取决于优化程序在确定完整执行计划时的进度。 -
Range checked for each record (index map:
(JSON属性:N
)message
)MySQL发现没有好的索引可以使用,但发现在前面的表的列值已知之后可能会使用某些索引。对于上表中的每个行组合,MySQL检查是否可以使用
range
或index_merge
访问方法来检索行。这不是很快,但比执行没有索引的连接更快。适用性标准如 第8.2.1.2节“范围优化”和 第8.2.1.3节“索引合并优化”中所述,除了前面的表的所有列值都是已知的并被认为是常量。索引从1开始编号,顺序
SHOW INDEX
与表中显示的顺序相同。索引映射值N
是一个位掩码值,指示哪些索引是候选。例如,值0x19
(二进制11001)表示将考虑索引1,4和5。 -
Scanned
(JSON属性:N
databasesmessage
)这表示服务器在处理
INFORMATION_SCHEMA
表查询时执行的目录扫描次数 ,如第8.2.3节“优化INFORMATION_SCHEMA查询”中所述。值N
可以是0,1或all
。 -
Select tables optimized away
(JSON属性:message
)优化器确定1)应该返回最多一行,以及2)为了产生该行,必须读取确定的行集。当在优化阶段(例如,通过读取索引行)读取要读取的行时,在查询执行期间不需要读取任何表。
当查询被隐式分组时(包含聚合函数但没有
GROUP BY
子句),满足第一个条件 。当每个使用的索引执行一行查找时,满足第二个条件。读取的索引数决定了要读取的行数。请考虑以下隐式分组查询:
SELECT MIN(c1),MIN(c2)FROM t1;
假设
MIN(c1)
可以通过读取一个索引行MIN(c2)
来检索,并且可以通过从不同的索引读取一行来检索。即,对于每一列c1
和c2
,存在其中列是索引的第一列的索引。在这种情况下,返回一行,通过读取两个确定行来生成。Extra
如果要读取的行不是确定性的,则不会出现 此值。考虑这个查询:SELECT MIN(c2)FROM t1 WHERE c1 <= 10;
假设这
(c1, c2)
是一个覆盖索引。使用此索引,c1 <= 10
必须扫描所有行以查找最小值c2
。相比之下,请考虑以下查询:SELECT MIN(c2)FROM t1 WHERE c1 = 10;
在这种情况下,第一个索引行
c1 = 10
包含最小值c2
。必须只读取一行才能生成返回的行。对于保持每个表的精确行数(例如
MyISAM
但不是InnoDB
)的存储引擎,对于缺少该子句或始终为true且没有 子句的查询,Extra
可能会出现此值。(这是隐式分组查询的实例,其中存储引擎会影响是否可以读取确定数量的行。)COUNT(*)
WHERE
GROUP BY
-
Skip_open_table
,Open_frm_only
,Open_full_table
(JSON属性:message
)这些值表示适用于
INFORMATION_SCHEMA
表查询的文件打开优化,如 第8.2.3节“优化INFORMATION_SCHEMA查询”中所述。-
Skip_open_table
:表文件不需要打开。通过扫描数据库目录,该信息已在查询中可用。 -
Open_frm_only
:只.frm
需要打开表的 文件。 -
Open_full_table
:未经优化的信息查找。的.frm
,.MYD
和.MYI
文件必须被打开。
-
-
Start temporary
,End temporary
(JSON属性:message
)这表示半连接重复Weedout策略的临时表使用。
-
unique row not found
(JSON属性:message
)对于诸如的查询,没有行满足 索引或表的条件。
SELECT ... FROM
tbl_name
UNIQUE
PRIMARY KEY
-
Using filesort
(JSON属性:using_filesort
)MySQL必须执行额外的传递以找出如何按排序顺序检索行。排序是通过根据连接类型遍历所有行并将排序键和指针存储到与该
WHERE
子句匹配的所有行的行来完成的。然后对键进行排序,并按排序顺序检索行。请参见 第8.2.1.14节“ORDER BY Optimization”。 -
Using index
(JSON属性:using_index
)仅使用索引树中的信息从表中检索列信息,而不必执行额外的搜索以读取实际行。当查询仅使用属于单个索引的列时,可以使用此策略。
对于
InnoDB
具有用户定义的聚簇索引的表,即使列中Using index
不存在 该索引,也可以使用该索引Extra
。这样的话,如果type
是index
和key
是PRIMARY
。 -
Using index condition
(JSON属性:using_index_condition
)通过访问索引元组并首先测试它们以确定是否读取完整的表行来读取表。以这种方式,索引信息用于推迟(“ 下推 ”)读取全表行,除非有必要。请参见 第8.2.1.5节“索引条件下推优化”。
-
Using index for group-by
(JSON属性:using_index_for_group_by
)与
Using index
表访问方法类似,Using index for group-by
表示MySQL找到了一个索引,可用于检索GROUP BY
或DISTINCT
查询的所有列,而无需对实际表进行任何额外的磁盘访问。此外,索引以最有效的方式使用,因此对于每个组,只读取少数索引条目。有关详细信息,请参见 第8.2.1.15节“GROUP BY优化”。 -
Using join buffer (Block Nested Loop)
,Using join buffer (Batched Key Access)
(JSON属性:using_join_buffer
)将早期联接中的表分成几部分读入连接缓冲区,然后从缓冲区中使用它们的行来执行与当前表的连接。
(Block Nested Loop)
表示使用块嵌套循环算法并(Batched Key Access)
指示使用批量密钥访问算法。也就是说,来自EXPLAIN
输出前一行的表中的键 将被缓冲,匹配的行将从Using join buffer
出现的行所代表的表中批量获取 。在JSON格式的输出,值
using_join_buffer
始终是中的任一个Block Nested Loop
或Batched Key Access
。 -
Using MRR
(JSON属性:message
)使用多范围读取优化策略读取表。请参见第8.2.1.10节“多范围读取优化”。
-
Using sort_union(...)
,Using union(...)
,Using intersect(...)
(JSON属性:message
)这些指示特定算法显示如何为
index_merge
连接类型合并索引扫描 。请参见第8.2.1.3节“索引合并优化”。 -
Using temporary
(JSON属性:using_temporary_table
)要解析查询,MySQL需要创建一个临时表来保存结果。如果查询包含以不同方式列出列的
GROUP BY
和ORDER BY
子句,则通常会发生这种情况。 -
Using where
(JSON属性:attached_condition
)甲
WHERE
子句用于限制匹配哪些行针对下一个表或发送到客户端。除非您特意打算从表中获取或检查所有行,否则如果Extra
值不是Using where
并且表连接类型为ALL
或者 ,则 查询中可能出现错误index
。Using where
在JSON格式的输出中没有直接的对应物; 该attached_condition
属性包含任何WHERE
使用的条件。 -
Using where with pushed condition
(JSON属性:message
)此产品适用于
NDB
表只。这意味着NDB Cluster正在使用条件下推优化来提高非索引列和常量之间直接比较的效率。在这种情况下,条件被“ 下推 ”到集群的数据节点,并在所有数据节点上同时进行评估。这消除了通过网络发送不匹配行的需要,并且可以在可以但不使用条件下推的情况下将这种查询加速5到10倍。有关更多信息,请参阅 第8.2.1.4节“发动机状态下推优化”。 -
Zero limit
(JSON属性:message
)查询有一个
LIMIT 0
子句,不能选择任何行。
摘自MySQL参考手册