在 MySQL 数据库优化中,查询性能至关重要。很多时候,SQL 语句执行缓慢,开发者需要找到 查询的瓶颈 并进行优化。MySQL 提供了 EXPLAIN 语句,帮助分析 SQL 的执行计划,揭示 索引使用情况、表的访问方式、连接顺序 等关键信息。本篇文章将详细讲解 EXPLAIN 的输出字段、如何解读执行计划,并提供 SQL 优化的最佳实践,帮助开发者高效分析和优化 MySQL 查询。


1. 什么是 EXPLAIN?

1.1 EXPLAIN 作用

EXPLAIN 主要用于分析 SELECT 查询 的执行计划,帮助开发者了解 MySQL 如何解析和优化查询。它可以:

查看 SQL 语句的执行方式(是否使用索引、查询优化方式)。

分析表的访问顺序(JOIN 顺序、是否发生全表扫描)。

判断索引是否生效(避免 Using filesortUsing temporary)。

找出查询的性能瓶颈 并进行优化。

1.2 EXPLAIN 语法

EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';

输出示例:

+----+-------------+-------+------------+------+---------------+------+---------+-------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+-------+----------------+
|  1 | SIMPLE      | users | NULL       | ref  | idx_email     | idx_email | 102 | const | Using index |
+----+-------------+-------+------------+------+---------------+------+---------+-------+----------------+

以上执行计划显示 users 表使用了 idx_email 索引,并且 没有发生全表扫描,查询性能较优。


2. EXPLAIN 输出字段解析

2.1 关键字段介绍

字段名作用重要性
id查询的执行顺序影响 JOIN 解析
select_typeSQL 查询类型(SIMPLESUBQUERY 等)影响优化方式
table查询涉及的表
partitions查询涉及的分区
type表访问类型(ALLindexrangerefeq_ref决定查询效率
possible_keys可能使用的索引
key实际使用的索引必须关注是否选用了合适的索引
key_len使用索引的长度索引字段的字节数,越短越优
ref索引匹配的列
rows预计扫描的行数影响查询性能
Extra额外信息,如 Using filesortUsing temporary查看是否存在查询优化问题

3. type 字段:表访问方式解读(性能排序)

type 字段表示 MySQL 访问表的方式,访问方式越高效,查询性能越好。

访问方式 (type)含义性能
system仅 1 行数据(系统表)✅ 极快
const通过 主键 / 唯一索引 查询单行数据✅ 极快
eq_ref唯一索引连接(如 JOIN 语句中使用 PRIMARY KEY✅ 快
ref普通索引连接(非唯一索引匹配多行)✅ 比较快
range索引范围扫描BETWEENIN>=⚠ 可能扫描较多数据
index索引全表扫描(扫描整个索引)⚠ 较慢
ALL全表扫描(无索引)❌ 最慢

📌 优化目标

  • 避免 ALL(全表扫描)。
  • 优先使用 refeq_refrange 方式,尽量减少扫描的行数。

4. Extra 字段:额外查询优化信息

Extra 字段展示了 查询的优化情况,部分值可能影响性能。

Extra 信息含义优化建议
Using index覆盖索引,查询只使用索引,无需回表✅ 最优
Using where需要 额外的过滤条件⚠ 建议优化索引
Using temporary使用了 临时表(如 GROUP BYORDER BY❌ 可优化索引,减少排序
Using filesort外部排序,性能较低❌ 尽量优化 ORDER BY,使用索引排序
Using join bufferJOIN 发生了额外的缓冲操作❌ 建立索引优化 JOIN
Using index condition索引条件筛选,但仍需回表查询⚠ 可以优化索引,减少回表操作

📌 优化目标

  • 避免 Using filesort,可通过 索引排序 解决。
  • 避免 Using temporary,可通过 优化 GROUP BY 语句 解决。
  • 使用 覆盖索引(Using index 提高查询效率。

5. EXPLAIN 执行计划优化案例

案例 1:全表扫描优化(type = ALL)

SQL 语句(未使用索引):

EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';

输出:

| id | select_type | table | type | possible_keys | key | rows | Extra |
|----|------------|-------|------|--------------|-----|------|-------|
| 1  | SIMPLE     | users | ALL  | NULL         | NULL | 100000 | Using where |

优化方案:

email 列添加索引,避免全表扫描:

CREATE INDEX idx_email ON users(email);

优化后 EXPLAIN 结果:

| id | select_type | table | type | possible_keys | key  | rows | Extra        |
|----|------------|-------|------|--------------|------|------|--------------|
| 1  | SIMPLE     | users | ref  | idx_email    | idx_email | 1 | Using index |

📌 优化效果:查询方式从 ALL(全表扫描)变为 ref,性能大幅提升。


案例 2:优化 ORDER BY,避免 Using filesort

未优化 SQL:

EXPLAIN SELECT * FROM orders ORDER BY created_at DESC;

输出:

| Extra            |
|-----------------|
| Using filesort |

优化方案:

CREATE INDEX idx_created_at ON orders(created_at DESC);

优化后,EXPLAIN 结果:

| Extra          |
|---------------|
| Using index   |

📌 优化效果ORDER BY 直接使用索引,避免 Using filesort,提高排序效率。


6. 结论

  • EXPLAIN 是优化 SQL 的关键工具,可以帮助分析 索引使用情况、查询优化方式
  • 避免全表扫描(type = ALL),尽量使用索引(refeq_ref)。
  • 关注 Extra 字段,避免 Using filesortUsing temporary
  • 利用覆盖索引Using index)减少回表,提高查询效率。

**掌握 EXPLAIN,SQL 性能优化从此得心应手!**🚀


📌 有什么问题和经验想分享?欢迎在评论区交流、点赞、收藏、关注! 🎯

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐