SQLPathLab
SQL 实战指南 · MySQL 8.0

使用 EXPLAIN 阅读查询计划

按访问方式、索引、预计行数和额外操作阅读 MySQL 8 EXPLAIN,并验证优化效果。

问题与判断方法

EXPLAIN 回答的是“优化器准备怎样执行”,不是“这条 SQL 最终用了多少毫秒”。在 MySQL 8 的表格结果中,先看 type、possible_keys、key、rows、filtered 和 Extra,逐表判断访问路径与预计工作量。

type 从 ALL、index 到 range、ref、const 通常表示定位范围逐步缩小,但不能脱离数据量判断。小表全表扫描可能合理;显示 possible_keys 也不代表实际选择了索引,真正使用的索引在 key 中。

对索引字段做计算或函数包装,常会让普通 B-tree 索引无法直接定位。例如 id + 0 = 3 与 id = 3 返回同一行,但后者让主键等值查找更容易被识别。这类可搜索条件也称为 sargable predicate。

需要实际执行数据时可使用 EXPLAIN ANALYZE,但它会真的运行查询。对 UPDATE、DELETE 或高成本语句应先在安全环境确认行为;分析结果还会受到数据分布、统计信息、缓存和参数值影响。

优化后同时核对结果正确性与计划变化:访问行数是否下降、选中的索引是否符合预期、是否仍有 Using filesort 或 temporary,以及新增索引带来的写入和存储成本。

示例

示例数据表

表名:orders
orders
idcustomer_idproduct_idnamedepartmentamountstatuscreated_atdiscount
1 101 201 Alice Sales 1200 paid 2026-01-03 0
2 102 202 Bob IT 900 pending 2026-01-08 50
3 101 201 Cindy Sales 1500 paid 2026-02-02 100
4 104 203 David HR 700 cancelled 2026-02-15 0

优化前 / 不推荐

EXPLAIN SELECT * FROM orders WHERE id + 0 = 3;

优化前运行结果

query_plan_summary
步骤对象访问方式说明注意事项
1 orders 顺序扫描 顺序读取 orders 并应用查询条件。 下表是帮助理解访问方式的概念摘要,不是 MySQL EXPLAIN 的原始列;索引选择、成本和预计行数应以目标 MySQL 环境的实际计划为准。

优化后 / 推荐

EXPLAIN SELECT * FROM orders WHERE id = 3;

优化后运行结果

query_plan_summary
步骤对象访问方式说明注意事项
1 orders 索引或键查找 通过示例数据中的索引或键路径读取 orders。 下表是帮助理解访问方式的概念摘要,不是 MySQL EXPLAIN 的原始列;索引选择、成本和预计行数应以目标 MySQL 环境的实际计划为准。

为什么这样更好:两种条件命中同一行,但直接对主键做等值比较可形成明确的键查找;对字段计算会破坏普通索引的直接定位条件。

这篇内容是否清楚?