探索 MySQL 扩展 EXPLAIN 输出格式
在数据库优化和性能调整的过程中,了解 SQL 查询的执行计划是至关重要的。MySQL 的 EXPLAIN
语句是一个强大的工具,用于分析查询的执行计划。从 MySQL 8.0.12 版本开始,EXPLAIN
提供了更多的扩展信息,这些信息对于深入理解查询优化和执行细节非常有用。
扩展 EXPLAIN 输出
EXPLAIN
语句现在能够产生额外的("扩展的")信息,这些信息不是 EXPLAIN
输出的一部分,但可以通过在 EXPLAIN
之后执行 SHOW WARNINGS
语句来查看。在 MySQL 8.0.12 之前,扩展信息只适用于 SELECT
语句。从 8.0.12 版本开始,扩展信息也适用于 DELETE
、INSERT
、REPLACE
和 UPDATE
语句。
SHOW WARNINGS
输出中的 Message
值显示了优化器如何在 SELECT
语句中限定表和列名,SELECT
在应用重写和优化规则后的样子,以及关于优化过程的其他可能的注释。
示例
让我们看一个扩展 EXPLAIN
输出的例子:
sql
mysql> EXPLAIN
SELECT t1.a, t1.a IN (SELECT t2.a FROM t2) FROM t1\G
这将产生类似于以下的输出:
sql
*************************** 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)
接下来,我们可以使用 SHOW WARNINGS
来查看扩展信息:
sql
mysql> SHOW WARNINGS\G
这将显示类似于以下的输出:
sql
*************************** 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)
这个输出展示了优化器如何处理查询,并且包含了特殊的标记,这些标记提供了关于查询重写或优化器行为的信息。这些标记包括 <auto_key>
、<cache>(expr)
、<exists>(query fragment)
等,每个都有其特定的含义。
结论
通过扩展的 EXPLAIN
输出,我们可以获得关于查询执行计划的更多细节,这对于调优和优化查询性能非常有帮助。需要注意的是,SHOW WARNINGS
显示的语句可能包含特殊标记,这些语句不一定是有效的 SQL,也不是用于执行的。这些信息主要用于理解优化器的行为和决策。在实际应用中,我们可以利