Explain

MySQL 的 EXPLAIN 是一个用于分析 SQL 查询执行计划的工具,它能帮助开发者理解查询的执行方式、索引使用情况、表之间的关联顺序等,从而优化查询性能。以下是对 EXPLAIN 的详细介绍:

1. 基本用法

在 SQL 语句前添加 EXPLAINEXPLAIN FORMAT=JSON 即可查看执行计划:

EXPLAIN SELECT * FROM users WHERE id = 1;

或者(输出更详细的 JSON 格式):

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

2. 输出字段解释

EXPLAIN 的结果包含以下关键字段:

字段名说明
id查询的标识符(同一查询的多个子查询可能共享相同 id)。
select_type查询类型(如 SIMPLE, PRIMARY, SUBQUERY, DERIVED, UNION 等)。
table当前操作涉及的表名。
partitions匹配的分区(如果表已分区)。
type访问类型(关键指标),性能从优到劣排序: system > const > eq_ref > ref > range > index > ALL
possible_keys可能使用的索引。
key实际使用的索引。
key_len使用的索引长度(字节)。
ref索引与哪些列或常量比较。
rows预估需要扫描的行数(越小越好)。
filtered过滤后剩余行数的百分比。
Extra额外信息(如 Using where, Using index, Using temporary, Using filesort 等)。

3. 关键字段详解

(1) type

  • const:通过主键或唯一索引直接找到一行(最优)。
  • eq_ref:联表查询时,主键或唯一索引匹配(如 JOIN ... ON a.id = b.id)。
  • ref:非唯一索引查找。
  • range:索引范围扫描(如 BETWEEN, IN, >)。
  • index:全索引扫描(比全表扫描稍快)。
  • ALL:全表扫描(需优化)。

(2) Extra

  • Using index:覆盖索引(无需回表)。
  • Using where:需在存储引擎返回后进一步过滤。
  • Using temporary:使用临时表(常见于 GROUP BYORDER BY 未用索引)。
  • Using filesort:需额外排序(可尝试用索引优化排序)。
  • Using index condition:索引下推

4. 优化示例

假设有一个查询:

EXPLAIN SELECT * FROM orders WHERE user_id = 100 ORDER BY order_date;

输出分析

  • 如果 typeALL,且 key 为空,说明未使用索引,全表扫描。
  • 优化方法:为 user_idorder_date 添加联合索引:

    ALTER TABLE orders ADD INDEX idx_user_order (user_id, order_date);

    优化后,type 应为 refExtra 显示 Using index

5. 注意事项

  1. 估算值rows 是统计信息估算的值,可能与实际有偏差。
  2. 不执行查询EXPLAIN 仅生成执行计划,不实际执行 SQL。
  3. 索引失效场景

    • 对索引列使用函数或运算(如 WHERE YEAR(date) = 2023)。
    • 数据类型不匹配(如字符串列用数字查询)。
    • 使用 ORLIKE '%前缀%'
  4. JSON 格式EXPLAIN FORMAT=JSON 提供更详细的执行步骤和成本估算。

6. 高级用法

  • EXPLAIN ANALYZE(MySQL 8.0+):实际执行查询并返回详细执行时间(慎用于生产环境):

    EXPLAIN ANALYZE SELECT * FROM users WHERE id = 1;
  • 优化器跟踪:查看优化器如何选择执行计划:

    SET optimizer_trace = 'enabled=on';
    SELECT * FROM users WHERE id = 1;
    SELECT * FROM information_schema.optimizer_trace;

通过 EXPLAIN 分析执行计划,可以快速定位慢查询的瓶颈,优化索引和 SQL 写法,显著提升数据库性能。

最后修改:2025 年 03 月 10 日
如果觉得我的文章对你有用,请随意赞赏