EXPLAIN 是 MySQL 中用于分析查询执行计划的关键工具,它能帮助你理解 MySQL 如何执行你的 SQL 查询,并找出可能的性能瓶颈。

基本用法

sql

EXPLAIN SELECT * FROM users WHERE id = 1;

对于 UPDATE/DELETE/INSERT 语句

sql

EXPLAIN UPDATE users SET name = 'John' WHERE id = 1;

MySQL 8.0+ 还支持更详细的格式

sql

EXPLAIN FORMAT=JSON SELECT * FROM users WHERE id = 1;

EXPLAIN 输出列解析

列名 描述
id 查询标识符,相同 id 表示同一查询部分,数字越大优先级越高
select_type 查询类型 (SIMPLE, PRIMARY, SUBQUERY, DERIVED 等)
table 访问的表名
partitions 匹配的分区
type 访问类型 (从最好到最差: system > const > eq_ref > ref > range > index > ALL)
possible_keys 可能使用的索引
key 实际使用的索引
key_len 使用的索引长度
ref 与索引比较的列或常量
rows 估计要检查的行数
filtered 表条件过滤的百分比
Extra 额外信息 (Using index, Using temporary, Using filesort 等)

关键字段详解

select_type

  • SIMPLE: 简单 SELECT (不包含子查询或 UNION)

  • PRIMARY: 最外层的 SELECT

  • SUBQUERY: 子查询中的第一个 SELECT

  • DERIVED: 派生表 (FROM 子句中的子查询)

  • UNION: UNION 中的第二个或后面的 SELECT 语句

  • UNION RESULT: UNION 的结果

type (非常重要)

  • system: 表只有一行记录 (系统表)

  • const: 通过主键或唯一索引一次就找到

  • eq_ref: 唯一索引扫描 (JOIN 中使用主键或唯一索引)

  • ref: 非唯一索引扫描

  • range: 索引范围扫描 (BETWEEN, <, >, IN 等)

  • index: 全索引扫描

  • ALL: 全表扫描 (性能最差)

Extra 常见值

  • Using index: 使用覆盖索引 (不需要回表)

  • Using where: 使用 WHERE 过滤

  • Using temporary: 使用临时表

  • Using filesort: 需要额外排序

  • Using join buffer: 使用连接缓冲

实际示例分析

sql

EXPLAIN SELECT u.name, o.order_date 
FROM users u 
JOIN orders o ON u.id = o.user_id 
WHERE u.status = 'active' 
ORDER BY o.order_date;

可能的结果分析:

id select_type table type possible_keys key rows Extra
1 SIMPLE u ref PRIMARY,status status 100 Using where
1 SIMPLE o ref user_id user_id 5 Using filesort

分析:

  1. 首先通过 status 索引查找 users 表中状态为 'active' 的记录

  2. 然后通过 user_id 索引关联 orders 表

  3. 最后需要对结果进行排序 (Using filesort)

优化建议

  1. 关注 type 列,尽量避免 ALL (全表扫描)

  2. 注意 Using filesort 和 Using temporary,它们通常表示性能问题

  3. rows 列可以帮助你估计查询成本

  4. 确保查询使用了适当的索引 (key 列)

MySQL 8.0+ 的 EXPLAIN ANALYZE 提供更详细的执行统计信息:

sql

EXPLAIN ANALYZE SELECT * FROM users WHERE id = 1;
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐