使用 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| id | customer_id | product_id | name | department | amount | status | created_at | discount |
|---|---|---|---|---|---|---|---|---|
| 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;优化前运行结果
| 步骤 | 对象 | 访问方式 | 说明 | 注意事项 |
|---|---|---|---|---|
| 1 | orders | 顺序扫描 | 顺序读取 orders 并应用查询条件。 | 下表是帮助理解访问方式的概念摘要,不是 MySQL EXPLAIN 的原始列;索引选择、成本和预计行数应以目标 MySQL 环境的实际计划为准。 |
优化后 / 推荐
EXPLAIN SELECT * FROM orders WHERE id = 3;优化后运行结果
| 步骤 | 对象 | 访问方式 | 说明 | 注意事项 |
|---|---|---|---|---|
| 1 | orders | 索引或键查找 | 通过示例数据中的索引或键路径读取 orders。 | 下表是帮助理解访问方式的概念摘要,不是 MySQL EXPLAIN 的原始列;索引选择、成本和预计行数应以目标 MySQL 环境的实际计划为准。 |
为什么这样更好:两种条件命中同一行,但直接对主键做等值比较可形成明确的键查找;对字段计算会破坏普通索引的直接定位条件。
这篇内容是否清楚?
感谢反馈,我们会把它用于后续内容复核。