前提
explain提供 SELECT, DELETE, INSERT, REPLACE,和 UPDATE语句的解析。
explain输出格式
Column | JSON Name | Meaning |
---|---|---|
id | select_id | 显示 SELECT 标识符 |
select_type | None | 显示 SELECT 类型 |
table | table_name | 输出表的名称 |
partitions | partitions | 匹配的分区 |
type | access_type | 连接类型 |
possible_keys | possible_keys | 可能用到的索引或主键 |
key | key | 实际选择的索引或主键 |
key_len | key_length | 所选索引或主键的长度 |
ref | ref | 显示将哪些列或常量与列中指定的索引进行比较 |
rows | rows | mysql必须检查以执行查询的行数 |
filtered | filtered | 过滤百分比,100为不过滤 |
Extra | None | 如何解析查询的其他信息 |
ID
SELECT标识符。这是SELECT查询中的序号 。如果行引用其他行的联合结果,则该值可以是NULL。在这种情况下,该 table列显示一个值 ,表示该行引用值为和的行的并集
SELECT TYPE
这里显示了选择的类型,对应上表的select_type
select_type Value | JSON Name | Meaning |
---|---|---|
SIMPLE | None | 简单的 SELECT查询 (未使用 UNION 或子查询) |
PRIMARY | None | 最外面的 SELECT 查询 |
UNION | None | 第二个或更多 SELECT 语句在 UNION |
DEPENDENT UNION | dependent (true ) | 第二个或更多 SELECT 语句 UNION , 取决于外部查询 |
UNION RESULT | union_result | 返回 UNION 的结果 |
SUBQUERY | None | 第一个 SELECT 是子查询 |
DEPENDENT SUBQUERY | dependent (true ) | 第一个 SELECT 在子查询, 取决于外部查询 |
DERIVED | None | 派生表 |
MATERIALIZED | materialized_from_subquery | 物化子查询 |
UNCACHEABLE SUBQUERY | cacheable (false ) | 无法缓存结果的子查询,必须为外部查询的每一行重新计算 |
UNCACHEABLE UNION | cacheable (false ) | 属于不可缓存的子查询的第二个或后一个选择的 UNION 语句
|
table
输出行引用的表的名称。这也可以是以下值之一:
<unionM,N>:行指的是id值为M和的行 的 并集 N。
:该行是指用于与该行的派生表结果id的值 N。例如,派生表可能来自FROM子句中的子查询 。
:行引用id 值为的行的具体化子查询的结果
partitions
查询将匹配记录的分区。该值适用NULL于非分区表
type
连接类型
Type | Meaning |
---|---|
system | 该表只有一行(=系统表) 这是const连接类型的特例 |
const | 最多只有一个匹配行,在查询开头读取,只读取一次 |
eq_ref | 对于每个行组合,从该表中读取一行 |
ref | 对于每个行组合,将从此表中读取具有匹配索引值的所有行。连接仅使用键的最左前缀的索引,不包括主键和唯一索引 使用 = or < = > 计算 |
fulltext | 使用FULLTEXT 索引执行连接。 |
ref_or_null | 这种连接类型像 ref,但除此之外,MySQL还会对包含NULL值的行进行额外搜索。此连接类型优化最常用于解析子查询 |
index_merge | 此连接类型表示使用了索引合并优化。在这种情况下,key输出行中的列包含使用的索引列表 |
unique_subquery | 一个索引查找功能,它可以完全替换子查询以提高效率 value IN (SELECT primary_key FROM |
index_subquery | 类似于 unique_subquery。它替换IN子查询,但它适用于以下形式的子查询中的非唯一索引 value IN (SELECT key_column FROM |
range | 仅检索给定范围内的行,使用索引选择行 可使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE,或 IN() |
index | 该index联接类型是一样的 ALL,只是索引树被扫描 |
ALL | 对前面表格中的每个行组合进行全表扫描 |
possible_keys
possible_keys列表示MySQL可以从中选择查找此表中的行的索引,如果为NULL,则没有相关索引
key
该key列指示MySQL实际决定使用的索引
key_len
该key_len列指示MySQL决定使用的索引的长度
ref
显示将哪些列或常量与列中指定的索引进行比较,以 key从表中选择行。
rows
指示MySQL认为必须检查以执行查询的行数。
filtered
指示将按表条件过滤的表行的估计百分比。最大值为100,这意味着不会对行进行过滤
Extra
包含有关MySQL如何解析查询的其他信息
Extra | Meaning |
---|---|
Child of 'table' pushed join@1 | 此表被引用为table可以下推到NDB内核的联接中的子代,仅当启用了下推式联接时,才适用于NDB群集 |
const row not found | 对于诸如此类的查询,该表为空 |
Deleting all rows | 因为DELETE,某些存储引擎(例如MyISAM)支持一种处理程序方法,该方法以简单快捷的方式删除所有表行 |
Distinct | MySQL正在寻找不同的值,因此它在找到第一个匹配行后停止为当前行组合搜索更多行。 |
FirstMatch | 半连接FirstMatch连接快捷方式策略用于tbl_name。 |
Full scan on NULL key | 当优化程序无法使用索引查找访问方法时,子查询优化会作为回退策略发生这种情况。 |
Impossible HAVING | 该HAVING子句始终为false,不能选择任何行。 |
Impossible WHERE | 该WHERE子句始终为false,不能选择任何行。 |
Impossible WHERE noticed after reading const tables | MySQL已经读取了所有 const(和 system)表,并注意到该WHERE子句始终为false。 |
LooseScan(m..n) | 使用半连接LooseScan策略。 m并且 n是关键部件号。 |
No matching min/max row | 没有行满足查询的条件,例如 。 SELECT MIN(...) FROM ... WHERE condition |
no matching row in const table | 对于具有连接的查询,有一个空表或没有满足唯一索引条件的行的表。 |
No matching rows after partition pruning | 对于DELETE或 UPDATE,优化器在分区修剪后没有发现任何删除或更新的内容。 |
No tables used | 查询没有FROM子句,或者有 FROM DUAL子句。 |
Not exists | MySQL能够对LEFT JOIN 查询进行优化,并且在找到与LEFT JOIN标准匹配的行之后,不会检查此表中更多行以用于上一行组合 |
Plan isn't ready yet | EXPLAIN FOR CONNECTION当优化程序尚未完成为在命名连接中执行的语句创建执行计划时, 会出现此值 |
Range checked for each record | MySQL发现没有好的索引可以使用,但发现在前面的表的列值已知之后可能会使用某些索引 |
Scanned N databases | 这表示服务器在处理INFORMATION_SCHEMA表查询时执行的目录扫描次数 |
Select tables optimized away | 优化器确定1)应该返回最多一行,以及2)为了产生该行,必须读取确定的行集 |
Skip_open_table, Open_frm_only, Open_full_table | 这些值表示适用于INFORMATION_SCHEMA 表查询的文件打开优化 |
Start temporary,End temporary | 这表示临时表用于半连接Duplicate Weedout策略。 |
unique row not found | 对于诸如的查询,没有行满足 索引或表的条件 |
Using filesort | MySQL必须执行额外的传递以找出如何按排序顺序检索行。 |
Using index | 仅使用索引树中的信息从表中检索列信息,而不必执行额外的搜索以读取实际行。对于InnoDB具有用户定义的聚簇索引的表,即使列中Using index不存在 该索引,也可以使用该索引Extra,这样的话,如果 type是 index和 key是PRIMARY。 |
Using index condition | 通过访问索引元组并首先测试它们以确定是否读取完整的表行来读取表。 |
Using index for group-by | 与Using index表访问方法类似,Using index for group-by 表示MySQL找到了一个索引,可用于检索GROUP BY或 DISTINCT查询的所有列,而无需对实际表进行任何额外的磁盘访问。 |
Using join buffer | 将早期联接中的表分成几部分读入连接缓冲区,然后从缓冲区中使用它们的行来执行与当前表的连接 |
Using MRR | 使用多范围读取优化策略读取表 |
Using sort_union(...),Using union(...),Using intersect(...) | 这些指示特定算法显示如何为index_merge连接类型合并索引扫描 |
Using temporary | 要解析查询,MySQL需要创建一个临时表来保存结果 |
Using where | 甲WHERE子句用于限制匹配哪些行针对下一个表或发送到客户端。除非您特意打算从表中获取或检查所有行,否则如果Extra值不是 Using where并且表连接类型为ALL或者 ,则 查询中可能出现错误index。 |
Using where with pushed condition | 此产品适用于NDB 表只。这意味着NDB Cluster正在使用条件下推优化来提高非索引列和常量之间直接比较的效率。在这种情况下,条件被“ 下推 ”到集群的数据节点,并在所有数据节点上同时进行评估。这消除了通过网络发送不匹配行的需要,并且可以在可以但不使用条件下推的情况下将这种查询加速5到10倍。 |
Zero limit | 查询有一个LIMIT 0子句,不能选择任何行。 |
参考: