### 13.8.2 解释声明

[](<>)[](<>)

```
{EXPLAIN | DESCRIBE | DESC}
    tbl_name [col_name | wild]

{EXPLAIN | DESCRIBE | DESC}
    [explain_type]
    {explainable_stmt | FOR CONNECTION connection_id}

{EXPLAIN | DESCRIBE | DESC} ANALYZE [FORMAT = TREE] 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.html)和[`解释`](explain.html)陈述是同义词。在实践中，[`描述`](describe.html)关键字更常用于获取有关表结构的信息，而[`解释`](explain.html)用于获取查询执行计划（即 MySQL 如何执行查询的说明）。

下面的讨论使用[`描述`](describe.html)和[`解释`](explain.html)关键字与这些用途一致，但 MySQL 解析器将它们视为完全同义词。

-   [获取表结构信息](explain.html#explain-table-structure)

-   [获取执行计划信息](explain.html#explain-execution-plan)

-   [通过 EXPLAIN ANALYZE 获取信息](explain.html#explain-analyze)

#### 获取表结构信息

[`描述`](describe.html)提供有关表中列的信息：

```
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.html)是一个捷径[`显示列`](show-columns.html).这些语句还显示视图信息。描述为[`显示列`](show-columns.html)提供有关输出列的更多信息。看[第 13.7.7.5 节，“显示列语句”](show-columns.html).

默认，[`描述`](describe.html)显示有关表中所有列的信息。*`col_name`*，如果给定，是表中列的名称。在这种情况下，该语句仅显示命名列的信息。*`荒野`*，如果给定，是一个模式字符串。它可以包含 SQL`%`和`_`通配符。在这种情况下，该语句仅显示名称与字符串匹配的列的输出。除非字符串包含空格或其他特殊字符，否则无需将字符串括在引号内。

[](<>)[](<>)

这[`描述`](describe.html)提供语句是为了与 Oracle 兼容。

这[`显示创建表`](show-create-table.html),[`显示表状态`](show-table-status.html)， 和[`显示索引`](show-index.html)语句还提供有关表的信息。看[第 13.7.7 节，“显示语句”](show.html).

#### 获取执行计划信息

这[`解释`](explain.html)语句提供有关 MySQL 如何执行语句的信息：

-   [`解释`](explain.html)与[`选择`](select.html),[`删除`](delete.html),[`插入`](insert.html),[`代替`](replace.html)， 和[`更新`](update.html)陈述。在 MySQL 8.0.19 及更高版本中，它也适用于[`桌子`](table.html)陈述。

-   什么时候[`解释`](explain.html)与可解释语句一起使用时，MySQL 会显示来自优化器的有关语句执行计划的信息。也就是说，MySQL 解释了它将如何处理该语句，包括有关表如何连接以及以何种顺序连接的信息。有关使用的信息[`解释`](explain.html)要获取执行计划信息，请参阅[第 8.8.2 节，“解释输出格式”](explain-output.html).

-   什么时候[`解释`](explain.html)与`连接 *`连接ID`*`它不是可解释的语句，而是显示在命名连接中执行的语句的执行计划。看[第 8.8.4 节，“获取命名连接的执行计划信息”](explain-for-connection.html).

-   对于可解释的陈述，[`解释`](explain.html)生成可以使用显示的附加执行计划信息[`显示警告`](show-warnings.html).看[第 8.8.3 节，“扩展 EXPLAIN 输出格式”](explain-extended.html).

-   [`解释`](explain.html)对于检查涉及分区表的查询很有用。看[第 24.3.5 节，“获取有关分区的信息”](partitioning-info.html).

-   这`格式`选项可用于选择输出格式。`传统的`以表格格式显示输出。如果没有，这是默认值`格式`选项存在。`JSON`format 以 JSON 格式显示信息。在 MySQL 8.0.16 及更高版本中，`树`提供具有比查询处理更精确的描述的树状输出`传统的`格式;它是唯一显示哈希连接用法的格式（请参阅[第 8.2.1.4 节，“哈希连接优化”](hash-joins.html)) 并且总是用于`解释分析`.

[`解释`](explain.html)需要执行解释语句所需的相同权限。此外，[`解释`](explain.html)还需要[`显示视图`](privileges-provided.html#priv_show-view)任何解释视图的特权。[`解释...连接`](explain.html)还需要[`过程`](privileges-provided.html#priv_process)如果指定的连接属于不同的用户，则具有特权。

[](<>)

在...的帮助下[`解释`](explain.html)，您可以看到应该在哪里为表添加索引，以便通过使用索引查找行来更快地执行语句。你也可以使用[`解释`](explain.html)检查优化器是否以最佳顺序连接表。提示优化器使用与表命名顺序相对应的连接顺序[`选择`](select.html)声明，以声明开头`选择 STRAIGHT_JOIN`而不仅仅是[`选择`](select.html).（看[第 13.2.10 节，“SELECT 语句”](select.html).)

优化器跟踪有时可能会提供与[`解释`](explain.html).但是，优化器跟踪格式和内容可能会因版本而异。有关详细信息，请参阅[MySQL 内部：跟踪优化器](https://dev.mysql.com/doc/internals/en/optimizer-tracing.html).

如果您认为应该使用的索引没有被使用，请运行[`分析表`](analyze-table.html)更新表统计信息，例如键的基数，这可能会影响优化器所做的选择。看[第 13.7.3.1 节，“ANALYZE TABLE 语句”](analyze-table.html).

笔记

MySQL Workbench 具有 Visual Explain 功能，可提供[`解释`](explain.html)输出。看[教程：使用 Explain 提高查询性能](https://dev.mysql.com/doc/workbench/en/wb-tutorial-visual-explain-dbt3.html).

#### 通过 EXPLAIN ANALYZE 获取信息

MySQL 8.0.18 引入`解释分析`，它运行一个语句并产生[`解释`](explain.html)输出连同时间和额外的、基于迭代器的、关于优化器的期望如何匹配实际执行的信息。对于每个迭代器，提供以下信息：

-   预计执行成本

    （成本模型没有考虑一些迭代器，因此不包括在估算中。）

-   估计返回的行数

-   返回第一行的时间

-   返回所有行的时间（实际成本），以毫秒为单位

    （当有多个循环时，此图显示每个循环的平均时间。）

-   迭代器返回的行数

-   循环数

    查询执行信息显示使用`树`输出格式，其中节点代表迭代器。`解释分析`总是使用`树`输出格式。在 MySQL 8.0.21 及更高版本中，可以选择使用显式指定`格式=树`;以外的格式`树`仍然不受支持。

`解释分析`可以与[`选择`](select.html)语句，以及多表[`更新`](update.html)和[`删除`](delete.html)陈述。从 MySQL 8.0.19 开始，它也可以与[`桌子`](table.html)陈述。

从 MySQL 8.0.20 开始，您可以使用终止此语句[`终止查询`](kill.html)要么**CTRL-C**.

`解释分析`不能与`连接`.

示例输出：

```
mysql> EXPLAIN ANALYZE SELECT * FROM t1 JOIN t2 ON (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 scan on t2  (cost=0.06 rows=6)
(actual time=0.003..0.005 rows=6 loops=1)
    -> Hash
        -> Table scan on t1  (cost=0.85 rows=6)
(actual time=0.018..0.022 rows=6 loops=1)

mysql> EXPLAIN ANALYZE SELECT * FROM t3 WHERE 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 scan on t3  (cost=1.75 rows=15)
(actual time=0.017..0.019 rows=15 loops=1)

mysql> EXPLAIN ANALYZE SELECT * FROM t3 WHERE 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 scan on t3 using PRIMARY  (cost=1.26 rows=5)
(actual time=0.012..0.014 rows=5 loops=1)
```

示例输出中使用的表是由此处显示的语句创建的：

```
CREATE TABLE t1 (
    c1 INTEGER DEFAULT NULL,
    c2 INTEGER DEFAULT NULL
);

CREATE TABLE t2 (
    c1 INTEGER DEFAULT NULL,
    c2 INTEGER DEFAULT NULL
);

CREATE TABLE t3 (
    pk INTEGER NOT NULL PRIMARY KEY,
    i INTEGER DEFAULT NULL
);
```

显示的值`实际时间`在此语句的输出中以毫秒表示。
