【MySQL百日打怪升级第24天】EXPLAIN 执行计划解读 —— type/key/rows/Extra

简介: 本文详解MySQL执行计划核心字段:type(访问类型,ALL/index需警惕)、rows(扫描行数,重在比例)、Extra(性能关键,关注Using index/filesort等)。结合实战案例与索引优化技巧,助DBA及开发者快速定位慢查根源,直击面试高频考点。

EXPLAIN 执行计划解读 —— type/key/rows/Extra


大家好,我是一名拥有10年以上经验的DBA老兵。

做这个系列,源于一个朴素的愿望:把踩过的坑、总结的经验系统化输出,希望能帮到刚入行或想进阶的兄弟们。

让我们开始今天的第24天内容。


昨天讲了慢查询日志——找到"谁慢"。今天讲它的续篇:看出为什么慢。

答案就是 EXPLAIN。面试必问,工作必用。能把 type 和 Extra 聊透,面试官会觉得你真干活。


怎么用

EXPLAIN SELECT * FROM users WHERE age > 30;
-- MySQL 8.0+ 还支持
EXPLAIN FORMAT=TREE SELECT ...
EXPLAIN ANALYZE SELECT ...  -- 真的跑了,给实际耗时

EXPLAIN SELECT 只生成计划不跑数据。但 EXPLAIN ANALYZE 真的会跑。另外 EXPLAIN 会拿 MDL 锁,同时有 DDL 操作并发执行时会有锁等待风险。


type:你怎么找的数据?

执行计划里最核心的一列。按效率从高到低排:

type 含义 什么情况
const 最多返回一行,按主键/唯一索引查 WHERE id = 1
eq_ref 连表时每行匹配一行 JOIN 走主键
ref 普通索引等值匹配 WHERE status = 'active'
range 索引范围扫描 BETWEEN> <IN
index 遍历索引树 比 ALL 好一点,还是遍历
ALL 全表扫描 最差的,应该避免

面试最爱问 type 排序。出现 ALL 和 index 就要警惕——极小字典表全表扫描没问题,大表上出现 ALL,就是没走索引。


rows:优化器猜你要扫多少行

估算值,不是精确值。价值在看比例。

rows=500000 而你只预期几十行——索引有问题。如果估算和实际差距大,说明统计信息可能过时了,跑一下 ANALYZE TABLE


Extra:亮点都在这里

Extra 值 含义
Using index 覆盖索引,不回表,效率极高
Using where WHERE 条件未完全被索引过滤,服务器层再判断
Using index condition 索引条件下推(ICP)
Using filesort 无法用索引排序,需要关注
Using temporary 用了临时表,常见于 GROUP BY
Using where; Using index 理想状态

判断标准:type 到 ref/range 以上,Extra 不含 filesort/temporary。


实战:看个例子

EXPLAIN SELECT * FROM orders
WHERE status = 'pending'
ORDER BY created_at DESC
LIMIT 10\G

输出里三个红色警报:

type: ALL                 -- 全表扫描
rows: 500000              -- 逐行比对
Extra: Using where; Using filesort  -- 还要在内存里排序

瓶颈在哪?
MySQL 要先把 50 万行数据逐行读入内存,筛选出 status='pending' 的若干行,再对结果集做 filesort 排序,最后取前 10 条。IO + 排序 + 回表,三重开销。


修复:加一个复合索引

ALTER TABLE orders ADD INDEX idx_status_created (status, created_at);

为什么是这个顺序?
B+ 树索引的叶子节点天然按 (status, created_at) 有序存储。这意味着:

  1. 先通过 status='pending' 快速定位到索引片段(避免全表扫)
  2. 该片段内部已经按 created_at DESC 排好序(直接省略 filesort)
  3. 取前 10 条即可收工

再看执行计划:

type: ref
rows: 50
Extra: Using where
  • 扫描量:50 万 → 50,降了 1 万倍
  • 排序开销:filesort 直接消失
  • 唯一代价SELECT * 还要根据主键回表查其他字段(name、price 等)

为什么 "Using where" 还在,却反而更好了?

很多人看到 Extra: Using where 就紧张,其实它只是个中性标记,表示 "Server 层会用 WHERE 条件做过滤"。真正决定性能的是:它要在多少行上做过滤,以及是否伴随其他恶性操作

阶段 执行计划 实际含义
加索引前 type: ALL + rows: 500000 + Using where; Using filesort 先把 50 万行逐行读入内存,Server 层逐行过滤;过滤完还要在内存里排序(filesort)
加索引后 type: ref + rows: 50 + Using where 索引直接定位到 50 行匹配数据,Server 层只在这 50 行上确认条件;排序已经由索引的有序性完成,filesort 消失

所以 "Using where" 没变,但它工作的上下文彻底变了

  • 优化前:它是劳动密集型——在 50 万行里大海捞针
  • 优化后:它是确认型——索引已经把数据筛到 50 行了,Server 层只是做最终校验,而且省掉了 filesort 和全表 IO

如果看到 Using where 就慌,那覆盖索引里的 Using where; Using index 你怎么解释?后者可是最佳实践。

真正该警惕的 Extra 组合是 Using where; Using filesort(全表扫 + 文件排序),而不是 Using where 本身。看 Extra 不能只看标签,要看它跟在什么 type 和 rows 后面。 ALL + Using where 是灾难,ref + Using where 是健康。


再进一步:覆盖索引

如果业务上只关心这两列,把查询改成:

SELECT status, created_at FROM orders
WHERE status = 'pending'
ORDER BY created_at DESC
LIMIT 10;

执行计划会变成:

Extra: Using where; Using index

此时连回表都省了——索引叶子节点里已经存了需要的全部数据,MySQL 不会再去碰主键索引。这就是覆盖索引


📝 面试解答

Q: type=index 和 ALL 哪个更差?

多数情况下 index 比 ALL 好一点——索引比数据文件小,遍历的 IO 更少。但索引不能覆盖且要回表时,index 反而比 ALL 更差:全扫描索引树产生大量随机回表 I/O,不如 ALL 的顺序读。所以不能只看 type,要结合 Extra 是不是 Using index 一起判断。

Q: Using filesort 一定会写磁盘吗?

不一定。数据量小在 sort_buffer 内存排序,超过 sort_buffer_size 才写磁盘。但出现 filesort 就是需要关注了。


⚠️ 几个坑

  • EXPLAIN 是估算EXPLAIN ANALYZE 才是真实执行
  • 参数绑定影响计划,分析时用具体值代替 ?

🤖 AI实战工具箱:让AI当你的EXPLAIN陪练

玩法一:AI出题你来判

跟 AI 说:

你现在是 MySQL 面试官。随机生成 5 个 EXPLAIN 输出,里面有好的有坏的。每次给我一个,我判断 type 和 Extra 有没有问题,你再告诉我对不对。最后总结我的水平。

AI 可能会出这样的题:

SQL: SELECT * FROM users WHERE status = 'active'
type: ref   key: status   rows: 500   Extra: NULL

或这样的题:

SQL: SELECT * FROM orders ORDER BY created_at DESC LIMIT 10
type: ALL   key: NULL   rows: 100000   Extra: Using filesort

练完 5 道,AI 会告诉你错了几道、哪类问题老是漏判。

玩法二:没有数据库也能练

手边没 MySQL?让 AI 模拟:

假设有一张订单表 orders(id, user_id, status, amount, created_at),50 万行。status 有普通索引。给我 3 条查询加 EXPLAIN 输出,分析哪条最优、哪条最差、为什么。

AI 生成的执行计划虽然不真实,但判断逻辑是一样的


思考题

🤔 互动时间:

  1. 你的业务 SQL 里有没有 type=ALL 的?今天给了你什么思路?
  2. EXPLAIN ANALYZE 和普通 EXPLAIN 什么区别?
  3. Extra 出现 Using filesort 但 SQL 没写 ORDER BY,怎么查?

总结

🎯 面试考点

  • type 排序:const > eq_ref > ref > range > index > ALL
  • rows 列:估算值,看比例而非绝对值
  • Extra 核心Using index(好)、Using filesort/temporary(要优化)
  • EXPLAIN 是估算EXPLAIN ANALYZE 才是真实执行
  • 调优标准:type ≥ ref/range,Extra 不含 filesort/temporary

今天就试一下:找个你常用的查询,前面加 EXPLAIN 跑一遍。看一眼 type 和 Extra。如果 type=ALL 或 Extra=Using filesort——这就是你今天要优化的事。

下期预告:索引失效的典型场景 —— 面试必问!


有问题欢迎评论区交流,明天见!

相关文章
|
1天前
|
人工智能 安全 PHP
周一上线|Claude Code 有了避坑指南,GitHub 内部仓库遭未授权访问
本周AI/开发者圈“工具与玩具齐飞”:Cursor、Warp、Codex、Qwen等密集升级;Google开源Agent Runtime,Perplexity发布安全扫描器;老式钻床变游戏手柄、耳机成陀螺发射器、3D猫追鼠标等创意玩出花。
周一上线|Claude Code 有了避坑指南,GitHub 内部仓库遭未授权访问
|
1天前
|
编解码 人工智能 自然语言处理
从 VALL-E 到 MaskGCT:零样本声音克隆技术演进
本文梳理零样本声音克隆从VALL-E(自回归)到MaskGCT(非自回归掩码生成)的技术演进,聚焦视频翻译配音这一高要求场景:需兼顾多角色一致性、跨语种音色保真、副语言细节(笑/叹气/情绪)、时间轴对齐与批量稳定性。工程落地重于单句demo,核心在于长视频中“像角色说话”,而非仅“读准文本”。
|
1天前
|
人工智能 前端开发 数据可视化
向量空间JBoltAI v4.4:ReAct推理链走向全透明
向量空间JBoltAI v4.4聚焦“可解释性”痛点,重构Agent架构:拆分AgentRAG与DataChatChain,统一推理基座;新增实时推理可视化(Thought/Action/Observation),全程可追溯;强化图表生成、安全认证与SDK模型生态。让AI从黑盒走向透明、可信、可管可控。(239字)
30 0
|
1天前
|
机器学习/深度学习 数据采集 人工智能
水稻病害检测数据集分享(适用于YOLO系列深度学习分类检测任务)
本数据集含7000+张水稻病害图像,覆盖细菌性叶斑病、褐斑病、叶霉病三类,标注规范(YOLO格式),已划分训练/验证/测试集(8:1:1),支持YOLO系列等主流检测模型,助力智慧农业病害识别研究与落地。(239字)
45 7
|
1天前
|
人工智能 自然语言处理 数据挖掘
一人公司办公必备
一人公司办公必备,是任务拆解+AI协同+智能体辅助+知识沉淀+工作流复用的个人系统。告别单点工具堆砌,聚焦流程化、可复用、能进化的高效办公范式。
42 2
|
1天前
|
机器学习/深度学习 自然语言处理 算法
图解强化学习 |手算GRPO
GRPO(分组相对策略优化)是PPO的无Critic简化版,仅用单一Actor网络,通过组内候选回答的相对奖励归一化替代优势函数估计;引入裁剪机制与KL正则,显著降低显存开销、提升训练稳定性与长链推理能力。(239字)
43 4
|
1天前
|
数据采集 人工智能 JSON
基于浏览器请求录制与AI代码生成的E2E接口自动化测试实践
以阿里云DataWorks为例,介绍如何通过浏览器录制插件捕获真实请求数据,结合AI编程工具自动生成接口封装与测试用例,解决复杂平台产品自动化测试中接口多、参数杂、数据流深的核心难题。
|
1天前
|
数据采集 人工智能 运维
2026年大型企业怎么做数据治理?五大核心步骤与工具选型指南
本文聚焦2026年大型企业数据治理痛点,系统拆解“现状评估、组织重构、元数据治理、质量与安全闭环、持续运营”五大核心步骤,并以瓴羊Dataphin为标杆案例,详解其如何通过OneData方法论与AI能力,一站式支撑全链路治理落地,助力企业将数据治理从“成本中心”升级为“价值引擎”。(239字)
|
1天前
|
人工智能 缓存 安全
Qwen3.7 Max——阿里云百炼发布面向智能体时代的新一代旗舰模型,免费领100万Tokens体验!
阿里云百炼重磅发布Qwen3.7 Max——面向智能体时代的新一代旗舰大模型,支持100万tokens超长上下文、30K RPM高并发,具备卓越编程能力与MCP集成能力,可高效驱动复杂任务自主执行。现推理后付费限时5折,新用户免费试用100万Tokens。快速体验:https://t.aliyun.com/U/fPVHqY
|
1天前
|
JSON 运维 监控
线上CPU突然飙到500%,凶手竟是一条日志
一次CPU飙升至500%的故障,根源竟是一行日志:`logger.error(&quot;用户信息解析失败:&quot; + userJson)`。异常请求携带近5万行乱码JSON,导致高频字符串拼接与磁盘写入,拖垮CPU。通过线程栈定位、降级日志、规范输出(限流/精简/监控),成功止损。教训深刻:看似无害的日志,亦是性能杀手。