8.8.3 扩展的 EXPLAIN 输出格式

对于SELECT语句,EXPLAIN语句会产生额外的(“扩展”)信息,这些信息不是EXPLAIN输出的一部分,但可以通过在EXPLAIN之后发出SHOW WARNINGS语句来查看。 SHOW WARNINGS输出中的Message值显示优化器如何限定SELECT语句中的 table 名和列名,应用重写和优化规则后SELECT的外观以及有关优化过程的其他 Comments。

只能在SELECT语句中生成可在EXPLAIN之后用SHOW WARNINGS语句显示的扩展信息。 SHOW WARNINGS显示其他可解释语句(DELETEINSERTREPLACEUPDATE)的空结果。

Note

在较早的 MySQL 版本中,扩展信息是使用EXPLAIN EXTENDED生成的。仍然可以识别该语法以实现向后兼容性,但是默认情况下现在启用了扩展输出,因此EXTENDED关键字是多余的并且已弃用。它的使用会导致警告,并且它将在将来的 MySQL 版本中从EXPLAIN语法中删除。

这是扩展的EXPLAIN输出的示例:

mysql> EXPLAIN
       SELECT t1.a, t1.a IN (SELECT t2.a FROM t2) FROM t1\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: t1
         type: index
possible_keys: NULL
          key: PRIMARY
      key_len: 4
          ref: NULL
         rows: 4
     filtered: 100.00
        Extra: Using index
*************************** 2. row ***************************
           id: 2
  select_type: SUBQUERY
        table: t2
         type: index
possible_keys: a
          key: a
      key_len: 5
          ref: NULL
         rows: 3
     filtered: 100.00
        Extra: Using index
2 rows in set, 1 warning (0.00 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: /* select#1 */ select `test`.`t1`.`a` AS `a`,
         <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in
         ( <materialize> (/* select#2 */ select `test`.`t2`.`a`
         from `test`.`t2` where 1 having 1 ),
         <primary_index_lookup>(`test`.`t1`.`a` in
         <temporary table> on <auto_key>
         where ((`test`.`t1`.`a` = `materialized-subquery`.`a`))))) AS `t1.a
         IN (SELECT t2.a FROM t2)` from `test`.`t1`
1 row in set (0.00 sec)

由于SHOW WARNINGS显示的语句可能包含特殊标记以提供有关查询重写或优化程序操作的信息,因此该语句不一定是有效的 SQL,也不打算执行。输出还可能包含带有Message值的行,这些行提供有关优化程序采取的操作的其他非 SQL 解释性说明。

以下列 table 描述了可以在SHOW WARNINGS显示的扩展输出中出现的特殊标记:

  • <auto_key>

自动生成的临时 table 密钥。

  • <cache>(expr)

table 达式(例如标量子查询)执行一次,结果值保存在内存中以备后用。对于包含多个值的结果,可能会创建一个临时 table,您将看到<temporary table>

  • <exists>(query fragment)

子查询谓词将转换为EXISTS谓词,子查询将进行转换,以便可以与EXISTS谓词一起使用。

  • <in_optimizer>(query fragment)

这是一个内部优化器对象,对用户没有任何意义。

  • <index_lookup>(query fragment)

使用索引查找来处理查询片段以查找合格的行。

  • <if>(condition, expr1, expr2)

如果条件为 true,则求值为* expr1 ,否则为 expr2 *。

  • <is_not_null_test>(expr)

检验 table 达式不等于NULL的测试。

  • <materialize>(query fragment)

使用子查询实现。

  • ```materialized-subquery`.col_name``

实现对内部临时 table 中的* col_name *列的引用,以保存评估子查询的结果。

  • <primary_index_lookup>(query fragment)

使用主键查找来处理查询片段以查找合格的行。

  • <ref_null_helper>(expr)

这是一个内部优化器对象,对用户没有任何意义。

  • /* select#N */ select_stmt

SELECT与未扩展的EXPLAIN输出中具有id值* N *的行关联。

  • outer_tables semi join (inner_tables)

半联接操作。 * inner_tables *显示未拉出的 table。参见第 8.2.2.1 节“使用半联接转换优化子查询,派生 table 和视图引用”

  • <temporary table>

这 table 示为缓存中间结果而创建的内部临时 table。

当某些 table 为constsystem类型时,涉及这些 table 中列的 table 达式将由优化器尽早评估,并且不属于所显示语句的一部分。但是,对于FORMAT=JSON,某些consttable 访问将显示为使用 const 值的ref访问。