EXPLAIN语句
{EXPLAIN | DESCRIBE | DESC }
tbl_name [col_name | wild]
{EXPLAIN | DESCRIBE | DESC }
[explain_type]
{explainable_stmt | FOR CONNECTION connection_id}
{EXPLAIN | DESCRIBE | DESC } ANALYZE select_statement
explain_type: {
FORMAT = format_name
}
format_name: {
TRADITIONAL
| JSON
| TREE
}
explainable_stmt: {
SELECT statement
| TABLE statement
| DELETE statement
| INSERT statement
| REPLACE statement
| UPDATE statement
}
该DESCRIBE和EXPLAIN语句是同义词。实际上,DESCRIBE关键字通常用于获取有关表结构的信息,而EXPLAIN用于获取查询执行计划(即,有关MySQL如何执行查询的说明)。
以下讨论根据这些用法使用DESCRIBEand EXPLAIN关键字,但是MySQL解析器将它们视为完全同义词。
- 获取表结构信息
- 获取执行计划信息
- 使用EXPLAIN ANALYZE获取信息
获取表结构信息
DESCRIBE提供有关表中列的信息:
mysql>DESCRIBE City; +------------ +---------- +------ +----- +--------- +---------------- + | Field | Type | Null | Key | Default | Extra | +------------ +---------- +------ +----- +--------- +---------------- + | Id | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | Country | char(3) | NO | UNI | | | | District | char(20) | YES | MUL | | | | Population | int(11) | NO | | 0 | | +------------ +---------- +------ +----- +--------- +---------------- +
DESCRIBE是的快捷方式SHOW COLUMNS。这些语句还显示视图信息。的说明SHOW COLUMNS提供了有关输出列的更多信息。请参见“ SHOW COLUMNS语句”。
默认情况下,DESCRIBE显示有关表中所有列的信息。col_name(如果给出)是表中列的名称。在这种情况下,该语句仅显示有关命名列的信息。wild(如果给出)是模式字符串。它可以包含SQL %和_通配符。在这种情况下,该语句仅显示名称与字符串匹配的列的输出。除非字符串包含空格或其他特殊字符,否则无需将其用引号引起来。
DESCRIBE提供该语句是为了与Oracle兼容。
SHOW CREATE TABLE,SHOW TABLE STATUS和SHOW INDEX语句也可以提供有关表的信息。请参见“ SHOW语句”。
获取执行计划信息
该EXPLAIN语句提供有关MySQL如何执行语句的信息:
EXPLAIN作品有SELECT,DELETE,INSERT,REPLACE,和UPDATE语句。在MySQL 8.0.19和更高版本中,它也可用于TABLE语句。- 当
EXPLAIN与可解释的语句一起使用时,MySQL将显示来自优化器的有关语句执行计划的信息。也就是说,MySQL解释了它将如何处理该语句,包括有关如何连接表以及以何种顺序连接表的信息。有关EXPLAIN用于获取执行计划信息的信息,请参见“ EXPLAIN输出格式”。 - 当
EXPLAIN与而不是可解释的语句一起使用时,它将显示在命名连接中执行的语句的执行计划。请参见“获取命名连接的执行计划信息”。FOR CONNECTION connection_id - 对于可解释的语句,
EXPLAIN生成可以使用来显示的其他执行计划信息SHOW WARNINGS。 EXPLAIN对于检查涉及分区表的查询很有用。请参见“获取有关分区的信息”。- 该
FORMAT选项可用于选择输出格式。TRADITIONAL以表格格式显示输出。如果不FORMAT存在任何选项,则为默认设置。JSONformat以JSON格式显示信息。在MySQL 8.0.16和更高版本中,TREE提供了类似于TRADITIONAL格式的树状输出,其中对查询处理的描述更为精确。它是唯一显示哈希联接用法的格式(请参见“哈希联接优化”),并且始终用于EXPLAIN ANALYZE。
EXPLAIN需要对所SELECT访问的任何表或视图(包括视图的任何基础表)具有特权。对于视图,EXPLAIN还需要SHOW VIEW特权。如果指定的连接属于其他用户,则EXPLAIN ... FOR CONNECTION还需要PROCESS特权。
在的帮助下EXPLAIN,您可以看到应该在表中添加索引的位置,以便通过使用索引查找行来使语句更快地执行。您还可以EXPLAIN用来检查优化器是否以最佳顺序联接表。要提示优化器使用连接顺序,该连接顺序与SELECT语句中表的命名顺序相对应,请以SELECT STRAIGHT_JOIN而不是just 开头SELECT。(请参见“ SELECT语句”。)
优化程序跟踪有时可能提供与补充的信息EXPLAIN。但是,优化程序的跟踪格式和内容在版本之间可能会发生变化。有关详细信息,请参见 MySQL内部:跟踪优化器。
如果您在认为应该使用索引时遇到问题,请运行ANALYZE TABLE以更新表统计信息,例如键的基数,这可能会影响优化器的选择。请参见“ ANALYZE TABLE语句”。
注意MySQL Workbench具有可视解释功能,可提供
EXPLAIN输出的可视表示。请参阅教程:使用解释来提高查询性能。
使用EXPLAIN ANALYZE获取信息
MySQL 8.0.18引入EXPLAIN ANALYZE,该语句运行一条语句并生成EXPLAIN输出,以及有关优化器的期望如何与实际执行相匹配的时间以及基于迭代器的其他信息。对于每个迭代器,提供以下信息:
估计执行成本
(某些迭代器未由成本模型考虑,因此未包含在估算中。)
- 预计返回的行数
- 是时候返回第一行
返回所有行的时间(实际成本),以毫秒为单位
(当存在多个循环时,此图显示每个循环的平均时间。)
- 迭代器返回的行数
- 循环数
使用TREE输出格式显示查询执行信息,其中节点表示迭代器。EXPLAIN ANALYZE始终使用TREE输出格式。在MySQL 8.0.20及更高版本中,可以选择使用FORMAT=TREE;显式指定它。除TREE不支持的格式外。
EXPLAIN ANALYZE可以与SELECT语句以及多表UPDATE和DELETE语句一起使用。从MySQL 8.0.19开始,它也可以与TABLE语句一起使用。
从MySQL 8.0.20开始,您可以使用KILL QUERY或CTRL-C终止此语句。
EXPLAIN ANALYZE不能与一起使用FOR CONNECTION。
输出示例:
mysql>EXPLAIN ANALYZE SELECT *FROM t1JOIN t2ON (t1.c1 = t2.c2)\G *************************** 1. row *************************** EXPLAIN : -> Inner hash join (t2.c2 = t1.c1) (cost=4.70 rows=6) (actual time=0.032..0.035 rows=6 loops=1) ->Table scanon t2 ( cost=0.06rows =6) (actual time=0.003..0.005rows =6 loops=1) ->Hash ->Table scanon t1 ( cost=0.85rows =6) (actual time=0.018..0.022rows =6 loops=1) mysql>EXPLAIN ANALYZE SELECT *FROM t3WHERE i > 8\G*************************** 1. row *************************** EXPLAIN : -> Filter : (t3.i > 8) (cost=1.75 rows=5) (actual time=0.019..0.021 rows=6 loops=1) ->Table scanon t3 ( cost=1.75rows =15) (actual time=0.017..0.019rows =15 loops=1) mysql>EXPLAIN ANALYZE SELECT *FROM t3WHERE pk > 17\G*************************** 1. row *************************** EXPLAIN : -> Filter : (t3.pk > 17) (cost=1.26 rows=5) (actual time=0.013..0.016 rows=5 loops=1) ->Index range scanon t3using PRIMARY ( cost=1.26rows =5) (actual time=0.012..0.014rows =5 loops=1)
示例输出中使用的表是通过以下所示的语句创建的:
CREATE TABLE t1 ( c1 INTEGERDEFAULT NULL, c2 INTEGERDEFAULT NULL );CREATE TABLE t2 ( c1 INTEGERDEFAULT NULL, c2 INTEGERDEFAULT NULL );CREATE TABLE t3 ( pk INTEGER NOT NULLPRIMARY KEY , i INTEGERDEFAULT NULL );
actual time此语句的输出中显示的值以毫秒为单位。
