EXPLAIN Output Format

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: `EXPLAIN`语句提供MySQL执行详情,适用于SELECT、DELETE、INSERT等语句,为每个表返回一行信息,按处理顺序列出。MySQL使用嵌套循环连接处理连接,输出含分区信息及扩展信息。旧版中分区和扩展信息需用特定语法生成,现已默认启用。EXPLAIN输出包括id、select_type、table等列,展示查询执行细节。最新版本中,可视化工具进一步帮助理解查询性能。

EXPLAIN语句提供有关MySQL如何执行语句的信息。EXPLAIN适用于SELECT、DELETE、INSERT、REPLACE和UPDATE语句。
EXPLAIN为SELECT语句中使用的每个表返回一行信息。它按照MySQL在处理语句时读取表的顺序在输出中列出表。MySQL使用嵌套循环连接方法解析所有连接。这意味着MySQL从第一个表中读取一行,然后在第二个表、第三个表等中找到匹配的行。当处理完所有表后,MySQL会输出所选列并在表列表中回溯,直到找到有更多匹配行的表。从该表中读取下一行,并继续处理下一个表。

EXPLAIN输出包括分区信息。此外,对于SELECT语句,EXPLAIN会生成扩展信息,这些信息可以在EXPLAIN之后显示为SHOW WARNINGS(见第8.8.3节,“扩展的EXPLAIN输出格式”)。

注:
在较旧的MySQL版本中,分区和扩展信息是使用EXPLAIN PARTITIONS和EXPLAIN extended生成的。这些语法仍然被认为具有向后兼容性,但默认情况下分区和扩展输出现在已启用,因此PARTITIONS和extended关键字是多余的,并且已被弃用。使用它们会导致警告;预计在未来的MySQL版本中,它们将从EXPLAIN语法中删除。
不能在同一EXPLAIN语句中同时使用弃用的PARTITIONS和EXTENDED关键字。此外,这两个关键字都不能与FORMAT选项一起使用。
注:
MySQL Workbench具有可视化解释功能,可提供Explain输出的可视化表示。请参阅教程:使用Explain提高查询性能。

image.png

EXPLAIN Output Columns
本节介绍EXPLAIN生成的输出列。后面的部分提供了有关类型和额外列的更多信息。
EXPLAIN的每一行输出都提供了关于一个表的信息。每一行都包含表8.1“EXPLAIN输出列”中总结的值,并在表后进行了更详细的描述。列名显示在表的第一列中;当使用FORMAT=JSON时,第二列提供输出中显示的等效属性名。

image.png

image.png

id (JSON name: select_id)

SELECT标识符。这是查询中SELECT的序列号。如果该行引用其他行的并集结果,则该值可以为NULL。在这种情况下,表列显示了一个类似于的值,表示该行是指id值为M和N的行的并集。

select_type (JSON name: none)

SELECT的类型,可以是下表所示的任何类型。JSON格式的EXPLAIN将SELECT类型作为query_block的属性公开,除非它是SIMPLE或PRIMARY。JSON名称(如适用)也显示在表中。

image.png

DEPENDENT通常表示使用相关子查询。见第13.2.10.7节“相关子查询”。
从属子查询评估不同于无法实现的子查询评估。对于DEPENDENT SUBQUERY,对于来自其外部上下文的变量的每组不同值,子查询只会重新计算一次。
对于UNCACHEABLE SUBQUERY,会为外部上下文的每一行重新评估子查询。
子查询的可缓存性不同于查询缓存中查询结果的缓存(如第8.10.3.1节“查询缓存的操作方式”所述)。子查询缓存发生在查询执行期间,而查询缓存仅用于在查询执行完成后存储结果。

当您使用EXPLAIN指定FORMAT=JSON时,输出没有直接等效于select_type的单个属性;query_block属性对应于给定的SELECT。与刚才显示的大多数SELECT子查询类型等效的属性是可用的(一个例子是materialized_from_subquery for materialized),并在适当的时候显示。SIMPLE或PRIMARY没有JSON等价物。
非select语句的select_type值显示受影响表的语句类型。例如,对于DELETE语句,select_type是DELETE。

table (JSON name: table_name)

输出行所引用的表的名称。这也可以是以下值之一:
unionM,N:该行是指id值为M和N的行的并集。
derivedN:该行引用id值为N的行的派生表结果。例如,派生表可能来自from子句中的子查询。
subcyN:该行是指id值为N的行的物化子查询的结果。请参阅第8.2.2.2节“使用物化优化子查询”。

partitions (JSON name: partitions)

查询将从中匹配记录的分区。对于非分区表,该值为NULL。请参阅第22.3.5节“获取分区信息”。

type (JSON name: access_type)
连接类型。有关不同类型的描述,请参阅EXPLAIN连接类型。

possible_keys (JSON name: possible_keys)
possible_keys列表示MySQL可以从中选择查找此表中行的索引。请注意,此列完全独立于EXPLAIN输出中显示的表的顺序。这意味着possible_key中的一些键在实际中可能无法用于生成的表顺序。
如果此列为NULL(或在JSON格式的输出中未定义),则没有相关索引。在这种情况下,您可以通过检查WHERE子句来检查它是否引用了适合索引的一个或多个列,从而提高查询的性能。如果是这样,请创建一个适当的索引,并再次使用EXPLAIN检查查询。请参阅第13.1.8节“ALTER TABLE语句”。
要查看表具有哪些索引,请使用SHOW INDEX FROM tbl_name。

key (JSON name: key)
key列表示MySQL实际决定使用的键(索引)。如果MySQL决定使用一个可能的_keys索引来查找行,则该索引将作为键值列出。
key可以命名一个不在possible_keys值中的索引。如果所有可能的_keys索引都不适合查找行,但查询选择的所有列都是其他索引的列,则可能会发生这种情况。也就是说,命名索引覆盖了选定的列,因此尽管它不用于确定要检索哪些行,但索引扫描比数据行扫描更有效。

对于InnoDB,即使查询也选择了主键,辅助索引也可能覆盖所选列,因为InnoDB将主键值与每个辅助索引一起存储。如果键为NULL,MySQL找不到用于更有效地执行查询的索引。
要强制MySQL使用或忽略possible_keys列中列出的索引,请在查询中使用force index、use index或ignore index。见第8.9.4节“索引提示”。
对于MyISAM表,运行ANALYZE TABLE有助于优化器选择更好的索引。对于MyISAM表,myisamck-analyze也会执行相同的操作。见第13.7.2.1节“分析表声明”和第7.6节“MyISAM表维护和故障恢复”。

key_len (JSON name: key_length)
key_len列表示MySQL决定使用的密钥的长度。key_len的值使您能够确定MySQL实际使用的多部分密钥的多少部分。如果键列显示NULL,则key_len列也显示NULL。
由于密钥存储格式的原因,对于可以为NULL的列,密钥长度比NOT NULL列长一个。

ref (JSON name: ref)
ref列显示了将哪些列或常量与键列中指定的索引进行比较,以从表中选择行。
如果值是func,则使用的值是某个函数的结果。要查看哪个函数,请使用EXPLAIN后的SHOW WARNINGS查看扩展的EXPLAIN输出。该函数实际上可能是一个运算符,如算术运算符。

rows (JSON name: rows)
行列表示MySQL认为执行查询必须检查的行数。
对于InnoDB表,这个数字是一个估计值,可能并不总是准确的。

filtered (JSON name: filtered)

筛选列表示按表条件筛选的表行的估计百分比。最大值为100,这意味着没有对行进行过滤。从100开始递减的值表示过滤量增加。行显示了检查的估计行数,行×过滤显示了与下表连接的行数。例如,如果行数为1000,过滤后的行数为50.00(50%),则要与下表连接的行数是1000×50%=500。

Extra (JSON name: none)

此列包含有关MySQL如何解析查询的其他信息。有关不同值的描述,请参阅EXPLAIN附加信息。
Extra列没有对应的单个JSON属性;但是,此列中可能出现的值将作为JSON属性或消息属性的文本公开。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
关系型数据库 MySQL 索引
EXPLAIN Output Interpretation
通过分析`EXPLAIN`输出的行列乘积,可评估MySQL连接效率,估算查询所需检查的行数。该乘积还影响`max-join-size`系统变量对多表SELECT语句的执行与中止决策。示例展示了如何逐步优化多表连接,通过调整列类型和大小来减少行乘积,从而提高查询性能。最终,结合索引分析,实现更优的连接效果。
|
2月前
|
机器学习/深度学习 计算机视觉 Python
output
【9月更文挑战第14天】
31 1
|
3月前
|
SQL 关系型数据库 数据处理
在 Postgres 中使用FORMAT
【8月更文挑战第11天】
66 0
在 Postgres 中使用FORMAT
|
6月前
|
Python
完美解决丨ValueError: time data ‘2018/12/24‘ does not match format ‘%Y/%m/%d‘
完美解决丨ValueError: time data ‘2018/12/24‘ does not match format ‘%Y/%m/%d‘
|
数据库
解决which is not functionally dependent on columns in GROUP BY clause;...sql_mode=only_full_group_by
解决which is not functionally dependent on columns in GROUP BY clause;...sql_mode=only_full_group_by
278 0
|
数据库
Data truncation: Incorrect date value: ‘2022-11-28T16:00:00.000Z‘ for column ‘start_date‘ at row 1
Data truncation: Incorrect date value: ‘2022-11-28T16:00:00.000Z‘ for column ‘start_date‘ at row 1
263 0
解决sql update 1292 - Truncated incorrect DOUBLE value:
出现这种错误,我属实焦头烂额了一会儿,这个错误基本可以分为以下两种情况: 一:你的字段类型是varchar,但是你这样进行操作,是不对的, UPDATE StuCose SET Cno=60 应该是: UPDATE StuCose SET Cno='60' 二:你更新操作进行子查询时,需要的两个表的相同的字段的类型不同,比如你的cose表中的Cno是int类型, 但是你的stucose表中是varchar类型 ,这个时候类似这样进行了子查询的update就会报错 UPDA.
612 0
解决sql update 1292 - Truncated incorrect DOUBLE value:
|
SQL 关系型数据库 MySQL
Influx Sql系列教程四:series/point/tag/field
influxdb中的一条记录point,主要可以分为三类,必须存在的time(时间),string类型的tag,以及其他成员field;而series则是一个measurement中保存策略和tag集构成;
397 0
|
SQL Java 数据库连接
JPA异常:Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
JPA异常:Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
2035 0
|
Java
错误Batch update returned unexpected row count from update [0]; actual row count: 0;
错误Batch update returned unexpected row count from update [0]; actual row count: 0;   把开发过程中碰到的BUG累积下来也是一笔财富。
3703 0
错误Batch update returned unexpected row count from update [0]; actual row count: 0;