Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL EXPLAIN详解

MySQL EXPLAIN从执行计划到索引优化完全解读

作者:华章酱

EXPLAIN执行计划是MySQL性能优化的核心工具,其本质是通过解析SQL语句的执行路径,揭示数据库引擎的决策逻辑,这篇文章主要介绍了MySQL EXPLAIN从执行计划到索引优化的相关资料,需要的朋友可以参考下

前言

在 MySQL 数据库调优中,EXPLAIN 是开发者最强大的“照妖镜”。任何 SELECT 查询,只要在前面加上 EXPLAIN,MySQL 就会告诉你它打算怎么执行这条 SQL——用哪些索引、联表顺序、扫描多少行、有没有隐性问题。

本文将从实际开发视角,逐一拆解 EXPLAIN 输出中的每个字段,并给出可直接落地的优化判断标准。

一、EXPLAIN 是什么?

执行 EXPLAIN SELECT ... 后,MySQL 不会真实执行查询,而是返回执行计划,以表格形式展示每一步如何操作。

EXPLAIN SELECT * FROM user WHERE id = 1;

输出一行或多行,每一行代表一个步骤(单表访问、子查询、UNION 等)。

二、字段详解(按重要性排序)

1. id —— 步骤编号

子查询不一定比主查询后执行,DERIVED 表反而先执行。

2. select_type —— 查询类型

含义性能警示
SIMPLE简单查询,无子查询、无UNION✅ 正常
PRIMARY外层主查询-
SUBQUERY普通子查询⚠️ 可能慢
DERIVEDFROM 中的子查询(派生表)⚠️ 一般慢
UNIONUNION 中第二个及之后的查询⚠️
DEPENDENT SUBQUERY相关子查询(依赖外层)❌ 极慢,必须改 JOIN
UNCACHEABLE SUBQUERY每次执行都要重算❌ 极慢

重点关注DEPENDENT SUBQUERY 是性能杀手,几乎都应改写为 JOIN。

3. table —— 访问对象

可以是真实表名,也可能是 <derived2>(id=2 的派生表)或 <union1,2>

4. type —— 访问类型 ★★★★

最重要的字段之一,直接反映索引使用效率。性能从好到差

级别含义说明
system表只有一行系统表,极少见
const主键/唯一索引等值查询极快,最多匹配一行
eq_ref联表时被驱动表用主键/唯一索引联表最优
ref普通索引等值查询
range索引范围查询(>, <, IN, BETWEEN)尚可
index扫描整个索引树比全表快一点,但仍需回表
ALL全表扫描❌ 最差,大表必崩

优化红线type = ALL 且表数据量 > 10万行,必须加索引

5. possible_keys —— 可能使用的索引

列出候选索引。若为 NULL,说明该表无可用索引,必须创建。

6. key —— 实际使用的索引 ★★★★

7. key_len —— 使用的索引长度(字节)

关键作用:判断联合索引用到了几列

示例:联合索引 (a, b, c)

常见类型长度参考(utf8mb4):

8. ref —— 与索引比较的对象

9. rows —— 预计扫描行数 ★★★★

MySQL 估算值,非精确数值越大,查询越慢。优化目标就是让 rows 持续变小。

10. filtered —— 过滤后剩余比例(%)

存储引擎返回后,经过 WHERE 条件过滤还剩下的比例。越低越好,说明索引筛选能力强。

示例:rows = 1000, filtered = 10 → 预计最终返回 100 行。

11. Extra —— 额外信息 ★★★★★

最重要的补充说明直接暴露性能陷阱

好信号

含义
Using index覆盖索引,不回表,极快
Using where有 WHERE 条件过滤

警告信号(需优化)

含义处理建议
Using index condition索引条件下推(ICP)尚可,但可检查索引顺序
Using temporary用了临时表❌ GROUP BY 无索引,必须改
Using filesort文件排序(内存/磁盘)❌ ORDER BY 无索引,必须加
Using join buffer联表无索引,用缓存❌ 必须为被驱动表加索引

危险信号

含义
Using temporary; Using filesortGROUP BY + ORDER BY 完全没走索引
Impossible WHEREWHERE 条件永远为假
No tables used无 FROM 表

三、实战:5 分钟定位慢查询

拿到一条慢 SQL,按以下顺序逐列审查 EXPLAIN 结果:

第一步:先看type

第二步:再看key

第三步:看Extra

第四步:估算rows

四、典型案例优化全过程

原始慢查询

EXPLAIN 
SELECT * FROM order 
WHERE user_id = 123 
ORDER BY create_time DESC;

执行计划

结论:全表扫 50 万行,再在内存排序 → 极慢

添加索引

ALTER TABLE order ADD INDEX idx_user_time (user_id, create_time);

优化后执行计划

EXPLAIN 
SELECT * FROM order 
WHERE user_id = 123 
ORDER BY create_time DESC;

效果:50万行扫描 → 15行,排序消失。

五、总结:EXPLAIN 优化口诀

EXPLAIN 看计划,逐行拆开查:
type 是关键,ALL 是红线;
key 不为空,才算走索引;
rows 尽量小,越大越危险;
Extra 藏魔鬼,temporary 必须改,filesort 立即办;
覆盖索引最理想,Using index 放心赞。

写在最后

EXPLAIN 是 MySQL 性能优化的入场券。掌握它,你就能在索引设计、SQL 改写、架构选型上拥有判断力。

但 EXPLAIN 不是万能的:

因此,EXPLAIN + 慢查询日志 + 性能监控,才是完整的 MySQL 调优体系。

到此这篇关于MySQL EXPLAIN从执行计划到索引优化完全解读的文章就介绍到这了,更多相关MySQL EXPLAIN详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文