文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  EXPLAIN 语句

15.8.2 EXPLAIN 语句

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

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

{EXPLAIN | DESCRIBE | DESC} ANALYZE [FORMAT = TREE] [schema_spec] select_statement

{EXPLAIN | DESCRIBE | DESC} ANALYZE FORMAT = JSON INTO variable [schema_spec] 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
}

schema_spec:
FOR {SCHEMA | DATABASE} schema_name

DESCRIBEEXPLAIN 语句是同义词。实际上,DESCRIBE 关键字更常用于获取有关表结构的信息,而 EXPLAIN 用于获取查询执行计划(即,MySQL 将如何执行查询的说明)。

以下讨论使用 DESCRIBEEXPLAIN 关键字,符合这些用途,但 MySQL 解析器将它们视为完全同义词。

获取表结构信息

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       |                |
+------------+----------+------+-----+---------+----------------+

DESCRIBESHOW COLUMNS 的简写。这些语句还会显示视图的信息。有关 SHOW COLUMNS 描述的更多信息,请参见 第 15.7.7.6 节“SHOW COLUMNS 语句”

默认情况下,DESCRIBE 显示有关表中所有列的信息。如果给出 col_name,则为表中列的名称。在这种情况下,语句仅显示有关命名列的信息。如果给出 wild,则为模式字符串。它可以包含 SQL 的 %_ 通配符。在这种情况下,语句仅显示与字符串匹配的名称的列的输出。除非字符串包含空格或其他特殊字符,否则无需将其括在引号中。

提供 DESCRIBE 语句是为了与 Oracle 保持兼容。

SHOW CREATE TABLESHOW TABLE STATUSSHOW INDEX 语句也提供有关表的信息。请参见 第 15.7.7 节“SHOW 语句”

当用于获取有关表列的信息时,explain_format 系统变量不会影响 EXPLAIN 的输出。

获取执行计划信息

EXPLAIN 语句提供有关 MySQL 如何执行语句的信息

  • EXPLAINSELECTDELETEINSERTREPLACEUPDATETABLE 语句一起工作。

  • EXPLAIN 与可解释语句一起使用时,MySQL 显示来自优化程序有关语句执行计划的信息。也就是说,MySQL 解释了它将如何处理该语句,包括有关如何联接表以及联接顺序的信息。有关使用 EXPLAIN 获取执行计划信息的详细信息,请参见 第 10.8.2 节“EXPLAIN 输出格式”

  • EXPLAINFOR CONNECTION connection_id 而不是可解释语句一起使用时,它将显示在命名连接中执行的语句的执行计划。请参见 第 10.8.4 节“获取命名连接的执行计划信息”

  • 对于可解释的语句,EXPLAIN 会生成可使用 SHOW WARNINGS 显示的额外执行计划信息。请参见 第 10.8.3 节“扩展 EXPLAIN 输出格式”

  • EXPLAIN 用于检查涉及分区表的查询。请参见 第 26.3.5 节“获取有关分区的的信息”

  • 可以使用 FORMAT 选项选择输出格式。 TRADITIONAL 以表格格式显示输出。如果不存在 FORMAT 选项,则为默认格式。 JSON 格式以 JSON 格式显示信息。 TREE 提供树状输出,并比 TRADITIONAL 格式更详细地描述查询处理;它是唯一显示哈希联接使用情况的格式(参见 第 10.2.1.4 节“哈希联接优化”),并且始终用于 EXPLAIN ANALYZE

    在 MySQL 9.0 中,EXPLAIN 使用的默认输出格式(即,当它没有 FORMAT 选项时)由 explain_format 系统变量的值决定。此变量的精确效果将在本节后面描述。

    MySQL 9.0 支持在 EXPLAIN FORMAT=JSON 中使用额外的 INTO 选项,这使得能够将 JSON 格式的输出保存到用户变量中,例如

    mysql> EXPLAIN FORMAT=JSON INTO @myselect 
        ->     SELECT name FROM a WHERE id = 2;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT @myselect\G
    *************************** 1. row ***************************
    @myex: {
      "query_block": {
        "select_id": 1,
        "cost_info": {
          "query_cost": "1.00"
        },
        "table": {
          "table_name": "a",
          "access_type": "const",
          "possible_keys": [
            "PRIMARY"
          ],
          "key": "PRIMARY",
          "used_key_parts": [
            "id"
          ],
          "key_length": "4",
          "ref": [
            "const"
          ],
          "rows_examined_per_scan": 1,
          "rows_produced_per_join": 1,
          "filtered": "100.00",
          "cost_info": {
            "read_cost": "0.00",
            "eval_cost": "0.10",
            "prefix_cost": "0.00",
            "data_read_per_join": "408"
          },
          "used_columns": [
            "id",
            "name"
          ]
        }
      }
    }
    1 row in set (0.00 sec)

    这适用于任何可解释语句(SELECTTABLEINSERTUPDATEREPLACEDELETE)。这里显示了使用 UPDATEDELETE 语句的示例

    mysql> EXPLAIN FORMAT=JSON INTO @myupdate 
        ->   UPDATE a SET name2 = "garcia" WHERE id = 3;              
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> EXPLAIN FORMAT=JSON INTO @mydelete 
        ->     DELETE FROM a WHERE name1 LIKE '%e%';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT @myupdate, @mydelete\G
    *************************** 1. row ***************************
    @myupdate: {
      "query_block": {
        "select_id": 1,
        "table": {
          "update": true,
          "table_name": "a",
          "access_type": "range",
          "possible_keys": [
            "PRIMARY"
          ],
          "key": "PRIMARY",
          "used_key_parts": [
            "id"
          ],
          "key_length": "4",
          "ref": [
            "const"
          ],
          "rows_examined_per_scan": 1,
          "filtered": "100.00",
          "attached_condition": "(`db`.`a`.`id` = 3)"
        }
      }
    }
    @mydelete: {
      "query_block": {
        "select_id": 1,
        "table": {
          "delete": true,
          "table_name": "a",
          "access_type": "ALL",
          "rows_examined_per_scan": 2,
          "filtered": "100.00",
          "attached_condition": "(`db`.`a`.`name1` like '%e%')"
        }
      }
    }
    1 row in set (0.00 sec)

    您可以使用 MySQL JSON 函数处理此值,就像处理任何其他 JSON 值一样,例如使用这些示例使用 JSON_EXTRACT()

    mysql> SELECT JSON_EXTRACT(@myselect, "$.query_block.table.key");
    +----------------------------------------------------+
    | JSON_EXTRACT(@myselect, "$.query_block.table.key") |
    +----------------------------------------------------+
    | "PRIMARY"                                          |
    +----------------------------------------------------+
    1 row in set (0.01 sec)
    
    mysql> SELECT JSON_EXTRACT(@myupdate, "$.query_block.table.access_type") AS U_acc,
        ->        JSON_EXTRACT(@mydelete, "$.query_block.table.access_type") AS D_acc;
    +---------+-------+
    | U_acc   | D_acc |
    +---------+-------+
    | "range" | "ALL" |
    +---------+-------+
    1 row in set (0.00 sec)

    另请参见 第 14.17 节“JSON 函数”

    尝试在没有显式包含 FORMAT=JSON 的情况下使用 INTO 子句会导致 EXPLAIN 被拒绝,并出现 ER_EXPLAIN_INTO_IMPLICIT_FORMAT_NOT_SUPPORTED。无论当前 explain_format 系统变量的值如何,情况都是如此。

    INTO 子句不支持 EXPLAIN ANALYZE;它也不支持 FOR CONNECTION

    重要提示

    如果由于任何原因,要分析的语句被拒绝,用户变量将不会更新。

  • MySQL 9.0 支持 FOR SCHEMA 子句,这会导致 EXPLAIN 的行为就像要分析的语句是在命名数据库中执行的一样;FOR DATABASE 作为同义词受支持。这里显示了一个简单的使用示例

    mysql> USE b;
    Database changed
    mysql> CREATE SCHEMA s1;
    Query OK, 1 row affected (0.01 sec)
    
    mysql> CREATE SCHEMA s2;
    Query OK, 1 row affected (0.01 sec)
    
    mysql> USE s1;
    Database changed
    mysql> CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, c2 INT NOT NULL);
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> USE s2;
    Database changed
    mysql> CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, c2 INT NOT NULL, KEY i1 (c2));
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> USE b;
    Database changed
    mysql> EXPLAIN FORMAT=TREE FOR SCHEMA s1 SELECT * FROM t WHERE c2 > 50\G
    *************************** 1. row ***************************
    EXPLAIN: -> Filter: (t.c2 > 50)  (cost=0.35 rows=1)
        -> Table scan on t  (cost=0.35 rows=1)
    
    1 row in set (0.00 sec)
    
    mysql> EXPLAIN FORMAT=TREE FOR SCHEMA s2 SELECT * FROM t WHERE c2 > 50\G
    *************************** 1. row ***************************
    EXPLAIN: -> Filter: (t.c2 > 50)  (cost=0.35 rows=1)
        -> Covering index scan on t using i1  (cost=0.35 rows=1)
    
    1 row in set (0.00 sec)

    如果数据库不存在,该语句将被拒绝,并出现 ER_BAD_DB_ERROR。如果用户没有运行该语句的必要权限,该语句将被拒绝,并出现 ER_DBACCESS_DENIED_ERROR

    FOR SCHEMAFOR CONNECTION 不兼容。

EXPLAIN 需要执行解释语句所需的相同权限。此外,EXPLAIN 还需要解释视图的任何 SHOW VIEW 权限。如果指定的连接属于不同的用户,EXPLAIN ... FOR CONNECTION 还需要 PROCESS 权限。

explain_format 系统变量确定 EXPLAIN 用于显示查询执行计划时的输出格式。此变量可以取 FORMAT 选项使用的任何值,以及 DEFAULT 作为 TRADITIONAL 的同义词。以下示例使用 world 数据库中的 country 表,该表可以从 MySQL:其他下载 中获得

mysql> USE world; # Make world the current database
Database changed

检查 explain_format 的值,我们发现它具有默认值,并且 EXPLAIN(没有 FORMAT 选项)因此使用传统的表格输出

mysql> SELECT @@explain_format;
+------------------+
| @@explain_format |
+------------------+
| TRADITIONAL      |
+------------------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT Name FROM country WHERE Code Like 'A%';
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table   | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | country | NULL       | range | PRIMARY       | PRIMARY | 12      | NULL |   17 |   100.00 | Using where |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

如果我们将 explain_format 的值设置为 TREE,然后重新运行相同的 EXPLAIN 语句,则输出将使用树状格式

mysql> SET @@explain_format=TREE;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@explain_format;
+------------------+
| @@explain_format |
+------------------+
| TREE             |
+------------------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT Name FROM country WHERE Code LIKE 'A%';
+--------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                      |
+--------------------------------------------------------------------------------------------------------------+
| -> Filter: (country.`Code` like 'A%')  (cost=3.67 rows=17)
    -> Index range scan on country using PRIMARY over ('A' <= Code <= 'A????????')  (cost=3.67 rows=17)  |
+--------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

如前所述,FORMAT 选项会覆盖此设置。使用 FORMAT=JSON 而不是 FORMAT=TREE 执行相同的 EXPLAIN 语句表明情况确实如此

mysql> EXPLAIN FORMAT=JSON SELECT Name FROM country WHERE Code LIKE 'A%';
+------------------------------------------------------------------------------+
| EXPLAIN                                                                      |
+------------------------------------------------------------------------------+
| {
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "3.67"
    },
    "table": {
      "table_name": "country",
      "access_type": "range",
      "possible_keys": [
        "PRIMARY"
      ],
      "key": "PRIMARY",
      "used_key_parts": [
        "Code"
      ],
      "key_length": "12",
      "rows_examined_per_scan": 17,
      "rows_produced_per_join": 17,
      "filtered": "100.00",
      "cost_info": {
        "read_cost": "1.97",
        "eval_cost": "1.70",
        "prefix_cost": "3.67",
        "data_read_per_join": "16K"
      },
      "used_columns": [
        "Code",
        "Name"
      ],
      "attached_condition": "(`world`.`country`.`Code` like 'A%')"
    }
  }
}                                                                              |
+------------------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

要将 EXPLAIN 的默认输出返回到表格格式,请将 explain_format 设置为 TRADITIONAL。或者,您可以将其设置为 DEFAULT,它具有相同的效果,如下所示

mysql> SET @@explain_format=DEFAULT;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@explain_format;
+------------------+
| @@explain_format |
+------------------+
| TRADITIONAL      |
+------------------+
1 row in set (0.00 sec)

MySQL 9.0 支持 JSON 输出格式的两个版本。版本 1 是在 MySQL 8.2 及更早版本中始终使用的线性格式;这在 MySQL 9.0 中仍然是默认设置,并且在本文档中已显示的示例中使用。JSON 输出格式的版本 2 基于访问路径,旨在与未来版本的 MySQL Optimizer 保持兼容。您可以通过将 explain_json_format_version 服务器系统变量的值设置为 2 来切换到版本 2 格式,如以下示例中对之前示例中使用的相同 EXPLAIN 语句所示

mysql> SELECT @@explain_json_format_version;
+-------------------------------+
| @@explain_json_format_version |
+-------------------------------+
|                             1 |
+-------------------------------+
1 row in set (0.00 sec)

mysql> SET @@explain_json_format_version = 2;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@explain_json_format_version;
+-------------------------------+
| @@explain_json_format_version |
+-------------------------------+
|                             2 |
+-------------------------------+
1 row in set (0.00 sec)

mysql> EXPLAIN FORMAT=JSON SELECT Name FROM country WHERE Code LIKE 'A%';
+------------------------------------------------------------------------------+
| EXPLAIN                                                                      |
+------------------------------------------------------------------------------+
| {
  "query": "/* select#1 */ select `world`.`country`.`Name` AS `Name` from `world`.`country` where (`world`.`country`.`Code` like 'A%')",
  "inputs": [
    {
      "ranges": [
        "('A' &lt;= Code &lt;= 'A????????')"
      ],
      "covering": false,
      "operation": "Index range scan on country using PRIMARY over ('A' &lt;= Code &lt;= 'A????????')",
      "index_name": "PRIMARY",
      "table_name": "country",
      "access_type": "index",
      "estimated_rows": 17.0,
      "index_access_type": "index_range_scan",
      "estimated_total_cost": 3.668778400708174
    }
  ],
  "condition": "(country.`Code` like 'A%')",
  "operation": "Filter: (country.`Code` like 'A%')",
  "access_type": "filter",
  "estimated_rows": 17.0,
  "estimated_total_cost": 3.668778400708174
}                                                                              |
+------------------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

设置 explain_json_format_version = 2 还会启用对 EXPLAIN ANALYZE FORMAT=JSON 中的 INTO 子句的支持,这使您能够将 JSON 输出存储在用户变量中,如下所示

mysql> EXPLAIN FORMAT=JSON INTO @v1 SELECT Name FROM country WHERE Code LIKE 'A%';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @v1\G 
*************************** 1. row ***************************
@v1: {
  "query": "/* select#1 */ select `world`.`country`.`Name` AS `Name` from `world`.`country` where (`world`.`country`.`Code` like 'A%')",
  "inputs": [
    {
      "ranges": [
        "('A' &lt;= Code &lt;= 'A????????')"
      ],
      "covering": false,
      "operation": "Index range scan on country using PRIMARY over ('A' &lt;= Code &lt;= 'A????????')",
      "index_name": "PRIMARY",
      "table_name": "country",
      "access_type": "index",
      "estimated_rows": 17.0,
      "index_access_type": "index_range_scan",
      "estimated_total_cost": 3.668778400708174
    }
  ],
  "condition": "(country.`Code` like 'A%')",
  "operation": "Filter: (country.`Code` like 'A%')",
  "access_type": "filter",
  "estimated_rows": 17.0,
  "estimated_total_cost": 3.668778400708174
}                                                                              |
+------------------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

您可以使用该变量作为 JSON 函数的参数,从该值中获取特定的信息项,例如

mysql> SELECT JSON_EXTRACT(@v1,'$.index_name') AS iname,
    ->        JSON_EXTRACT(@v1, '$.table_name') AS tname\G
*************************** 1. row ***************************
iname: "PRIMARY"
tname: "country"
1 row in set (0.00 sec)

此形式的 EXPLAIN ANALYZE 需要显式的 FORMAT=JSON 子句,并且仅支持 SELECT 语句。可选的 FOR SCHEMA 选项也受支持,但不是必需的。(可以使用 FOR DATABASE 代替。)仅当 explain_json_format_version 等于 2 时,INTO 子句才支持 FORMAT=JSON;否则语句将失败,并出现 EXPLAIN ANALYZE 不支持 FORMAT=JSON,explain_json_format_version=1

使用版本 2 格式后,您可以通过将 explain_json_format_version 设置回 1(默认值)来使所有后续 EXPLAIN FORMAT=JSON 语句的 JSON 输出恢复到版本 1 格式。

explain_json_format_version 的值决定了所有使用它的 EXPLAIN 语句使用的 JSON 输出格式的版本,无论 JSON 格式是由于给定的 EXPLAIN 语句包含显式的 FORMAT=JSON 选项而使用,还是由于 explain_format 系统变量被设置为 JSON 而自动使用。

借助 EXPLAIN,您可以了解在哪些地方应该为表添加索引,以便通过使用索引查找行来更快地执行语句。您还可以使用 EXPLAIN 检查优化器是否以最佳顺序联接表。要提示优化器使用与 SELECT 语句中表命名的顺序相对应的联接顺序,请以 SELECT STRAIGHT_JOIN 而不是 SELECT 开头语句。(参见 第 15.2.13 节“SELECT 语句”。)

优化器跟踪有时会提供补充 EXPLAIN 的信息。但是,优化器跟踪的格式和内容在不同版本之间可能会发生变化。有关详细信息,请参阅 MySQL 内部机制:跟踪优化器

如果您遇到了索引在您认为应该使用时未被使用的问题,请运行 ANALYZE TABLE 来更新表统计信息,例如键的基数,这会影响优化器做出的选择。参见 第 15.7.3.1 节“ANALYZE TABLE 语句”

注意

MySQL Workbench 具有可视化 EXPLAIN 功能,提供 EXPLAIN 输出的可视化表示。参见 教程:使用 Explain 提高查询性能

使用 EXPLAIN ANALYZE 获取信息

EXPLAIN ANALYZE 运行一个语句并生成 EXPLAIN 输出以及计时信息,以及有关优化器预期如何与实际执行相匹配的基于迭代器的其他信息。对于每个迭代器,将提供以下信息

  • 估计执行成本

    (某些迭代器不受成本模型的计算,因此不包括在估计中。)

  • 估计返回的行数

  • 返回第一行的时间

  • 执行此迭代器(包括子迭代器,但不包括父迭代器)所花费的时间(以毫秒为单位)。

    (当存在多个循环时,此数字显示每个循环的平均时间。)

  • 迭代器返回的行数

  • 循环次数

查询执行信息使用 TREE 输出格式显示,其中节点表示迭代器。 EXPLAIN ANALYZE 始终使用 TREE 输出格式。这可以选择使用 FORMAT=TREE 明确指定;除了 TREE 之外的格式仍然不受支持。

EXPLAIN ANALYZE 可与 SELECT 语句、多表 UPDATEDELETE 语句以及 TABLE 语句一起使用。

您可以使用 KILL QUERYCTRL-C 终止此语句。

EXPLAIN ANALYZE 不能与 FOR CONNECTION 一起使用。

示例输出

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
);

此语句输出中 actual time 所示的值以毫秒为单位。

explain_formatEXPLAIN ANALYZE 具有以下影响

  • 如果此变量的值为 TRADITIONALTREE(或同义词 DEFAULT),EXPLAIN ANALYZE 将使用 TREE 格式。这确保此语句默认情况下继续使用 TREE 格式,正如在引入 explain_format 之前一样。

  • 如果 explain_format 的值为 JSONEXPLAIN ANALYZE 将返回错误,除非在语句中指定了 FORMAT=TREE。这是因为 EXPLAIN ANALYZE 仅支持 TREE 输出格式。

我们在此说明第二点中描述的行为,重新使用上一个示例中的最后一个 EXPLAIN ANALYZE 语句

mysql> SET @@explain_format=JSON;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@explain_format;
+------------------+
| @@explain_format |
+------------------+
| JSON             |
+------------------+
1 row in set (0.00 sec)

mysql> EXPLAIN ANALYZE SELECT * FROM t3 WHERE pk > 17\G
ERROR 1235 (42000): This version of MySQL doesn't yet support 'EXPLAIN ANALYZE with JSON format'

mysql> EXPLAIN ANALYZE FORMAT=TRADITIONAL SELECT * FROM t3 WHERE pk > 17\G
ERROR 1235 (42000): This version of MySQL doesn't yet support 'EXPLAIN ANALYZE with TRADITIONAL format'

mysql> EXPLAIN ANALYZE FORMAT=TREE 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)

使用 FORMAT=TRADITIONALFORMAT=JSONEXPLAIN ANALYZE 始终会导致错误,无论 explain_format 的值如何。

在 MySQL 9.0 中,EXPLAIN ANALYZEEXPLAIN FORMAT=TREE 输出中的数字将根据以下规则格式化

  • 0.001-999999.5 范围内的数字将打印为十进制数。

    小于 1000 的十进制数具有三位有效数字;其余的具有四位、五位或六位有效数字。

  • 超出 0.001-999999.5 范围的数字将以工程格式打印。此类值的示例为 1.23e+9934e-6

  • 不打印尾随零。例如,我们打印 2.3 而不是 2.30,以及 1.2e+6 而不是 1.20e+6

  • 小于 1e-12 的数字将打印为 0