好的,我们来详细分析如何通过 EXPLAIN 分析 SQL 语句的优劣:
使用 explain 关键字分析 sql 语句,根据执行结果动态调整 sql 语句。

📊 1. EXPLAIN 的作用
EXPLAIN 是 SQL 优化的重要工具,用于展示数据库执行查询时的执行计划。通过分析其输出结果,可判断:
- 是否使用了索引
- 表连接顺序是否合理
- 是否存在全表扫描等性能瓶颈
🔍 2. 核心分析指标
执行计划中的以下字段需重点关注:
✅ type(访问类型)
表示表的访问方式,性能从优到劣排序:
| 类型 | 说明 |
|---|---|
system |
系统表,最优 |
const |
通过主键或唯一索引访问(如 WHERE id = 1) |
eq_ref |
多表连接时使用唯一索引(如 A.id = B.primary_key) |
ref |
使用非唯一索引(如 WHERE index_col = value) |
range |
索引范围扫描(如 BETWEEN, IN) |
index |
全索引扫描(遍历索引树) |
ALL |
全表扫描,需优化 |
👉 优化建议 :避免出现 ALL,尽量提升至 ref 及以上。
✅ key(实际使用的索引)
- 显示实际使用的索引名,若为
NULL表示未使用索引 - 对比
possible_keys(可能使用的索引)可判断索引选择是否合理
✅ rows(扫描行数)
- 预估需要扫描的行数,值越小越好
- 若远大于实际输出行数,说明索引效率低
✅ Extra(附加信息)
关键提示信息:
| 提示 | 说明 |
|---|---|
Using index |
使用覆盖索引,无需回表 |
Using where |
在存储引擎层后过滤数据 |
Using temporary |
创建临时表 ,需优化(如 GROUP BY 未走索引) |
Using filesort |
额外排序 ,需优化(如 ORDER BY 未走索引) |
Using join buffer |
使用连接缓存,可能需调整 join_buffer_size |
⚙️ 3. 优化案例对比
问题 SQL
SELECT * FROM orders WHERE user_id = 100 ORDER BY create_time;
未优化执行计划
type: ALL
key: NULL
rows: 10000
Extra: Using filesort
👉 问题:全表扫描 + 额外排序,性能差。
优化后(添加联合索引 (user_id, create_time))
type: ref
key: idx_user_create
rows: 1
Extra: Using index
👉 优化效果:索引覆盖查询,避免回表与排序。
💡 4. 优化建议总结
- 优先避免
ALL访问类型- 为
WHERE、JOIN条件字段添加索引
- 为
- 减少
filesort和temporary- 确保
ORDER BY/GROUP BY使用索引
- 确保
- 利用覆盖索引
- 使用联合索引包含查询字段(如
SELECT a,b→ 索引(a,b))
- 使用联合索引包含查询字段(如
- 控制
rows数量- 避免索引失效(如对索引列使用函数
WHERE YEAR(create_time)=2023)
- 避免索引失效(如对索引列使用函数
📝 5. 实践步骤
-
在 SQL 前添加
EXPLAIN:EXPLAIN SELECT ... FROM ... WHERE ...; -
重点关注
type、key、rows、Extra -
结合业务场景调整索引或改写 SQL
通过持续分析 EXPLAIN 结果,可逐步提升 SQL 执行效率 🚀。