执行计划深度解析:从 type 到 Extra,榨干 EXPLAIN 的价值

简介: 详解 MySQL EXPLAIN:从 type、key_len 到 Extra 各字段含义与优化技巧,用快递分拣等生动类比讲透执行计划。涵盖联合索引使用原则、filesort 本质、filtered 作用及实战调优案例,助你快速定位慢查询根源。

大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!

你肯定用过 EXPLAIN 看 SQL 的执行计划,但你有没有真正看全过?type 到底有几种取值?Extra 里的 Using index、Using where、Using temporary、Using filesort 分别什么意思?key_len 怎么算?filtered 有什么用?今天我们就来把 EXPLAIN 的输出彻底讲透。

  • type 相当于分拣效率:最快的是“直接按门牌号送”(const),最慢的是“翻遍整个仓库”(ALL)。
  • possible_keys = 可能用的传送带,key = 实际选的传送带。
  • rows = 需要检查的包裹数量。
  • filtered = 初步分拣后还需要人工二次分拣的比例。
  • Extra = 额外操作标记,如“用了传送带但还要人工挑拣”(Using where)、“需要临时堆货”(Using temporary)。

一、EXPLAIN 输出列完整解读

我们用 EXPLAIN SELECT ... 会得到一张表,每个列的含义如下:

列名 含义 关键点
id SELECT 的标识序号 越大越先执行;相同则从上到下
select_type 查询类型 SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION 等
table 表名或别名 可能是临时表名()
partitions 匹配的分区 分区表时有用
type 连接类型(重要) 性能从好到差:system > const > eq_ref > ref > range > index > ALL
possible_keys 可能使用的索引 列出候选索引
key 实际使用的索引 如果 NULL 表示没用到索引
key_len 使用索引的长度(字节) 判断联合索引用了多少列
ref 索引列与哪个值比较 常量 const 或 列名
rows 预估需要扫描的行数 越大越差
filtered 存储引擎返回的行中满足剩余条件的比例 100% 最好
Extra 额外信息 Using index、Using where、Using temporary、Using filesort 等

二、type 详解:性能的关键指标

type 表示 MySQL 如何查找表中的行,按性能从最优到最差排序:

type 含义 示例 出现条件
system 系统表,只有一行 极少见 系统表或 const 的特例
const 最多匹配一行,用主键或唯一索引等值查询 WHERE id = 1 主键或唯一索引,且查询结果为常量
eq_ref 使用唯一索引进行关联,每个关联只返回一行 JOIN ... ON t1.id = t2.id 且 t2.id 是主键 被驱动表使用主键或唯一索引连接
ref 使用非唯一索引或前缀索引进行等值匹配 WHERE name = 'abc'(name 有普通索引) 索引列不是唯一或可为 NULL
range 索引范围扫描 WHERE id BETWEEN 1 AND 100 或 IN、>、< 索引列上的范围条件
index 全索引扫描 索引覆盖但没过滤条件 遍历整个索引树
ALL 全表扫描(最差) 无索引或优化器认为全表更快 大表且无有效索引

优化目标:至少达到 range 级别,争取达到 ref 或 const。

案例:

-- type = ALL 很差
EXPLAIN SELECT * FROM orders WHERE amount > 100;
-- 添加索引后 type 变为 range
ALTER TABLE orders ADD INDEX idx_amount(amount);

三、Extra 详解:优化器还做了什么?

Extra 列包含关于查询执行的额外信息,很多关键优化线索都在这里:

Extra 信息 含义 优劣 优化方向
Using index 使用了覆盖索引,不回表 ✅ 好 继续保持
Using where 存储引擎返回后在 Server 层过滤 🟡 普通 尝试将过滤条件移到索引中
Using temporary 使用了临时表(通常用于 GROUP BY 或 DISTINCT) ⚠️ 差 优化 GROUP BY/ORDER BY 或加索引
Using filesort 需要额外排序,不能利用索引排序 ⚠️ 差 对 ORDER BY 列加索引
Using index condition 使用索引下推(ICP) ✅ 好 MySQL 5.6+ 自动优化
Using join buffer 连接使用了 Buffer(Block Nested Loop) 🟡 普通 加索引避免 Buffer
Impossible WHERE WHERE 条件永远为假 无需优化 检查 SQL 逻辑
No tables used 没有 FROM 或 FROM DUAL - -

注意:Using filesort 不是真的用文件,而是指无法利用索引排序,需要在内存或磁盘中排序。当排序结果集大时很慢。

案例:

-- Using filesort
EXPLAIN SELECT * FROM orders ORDER BY create_time;
-- 加索引后 Using filesort 消失
ALTER TABLE orders ADD INDEX idx_create_time(create_time);

四、组合索引与 key_len 实战

key_len 表示 MySQL 在索引中实际使用的字节数。通过它可判断联合索引使用了多少列。

计算规则:

  • 列长度:INT=4, BIGINT=8, DATE=3, TIMESTAMP=4, CHAR(n)=n×字符集字节数(utf8mb4=4),VARCHAR(n)=n×4+2。
  • 允许 NULL 额外 +1。

示例:索引 (user_id, log_date, type),user_id INT NOT NULL (4),log_date DATE NOT NULL (3),type TINYINT (1)。查询 WHERE user_id=1 AND log_date='2026-06-01' 则 key_len=4+3=7,说明用到了前两列。

联合索引使用原则:最左前缀,且中间的列不能跳过。如果跳过了某列,后面的列不会被使用。


五、filtered 的作用

filtered 表示存储引擎返回的行中,满足剩余 WHERE 条件的比例(估算)。100% 表示所有返回行都满足条件。如果 filtered 很小(如 10%),说明索引过滤后还要过滤掉 90% 的行,回表成本高。

用法:在 JOIN 中,驱动表的 filtered 值直接影响被驱动表的读取次数。


六、实战案例优化全过程

原始 SQL:

SELECT * FROM orders 
WHERE customer_id = 12345 
  AND status = 'PAID' 
  AND create_time > '2026-01-01'
ORDER BY create_time DESC
LIMIT 10;

原执行计划:type=ref,key=customer_id,rows=1000,Extra="Using where; Using filesort"。

问题分析:

  • 用了 customer_id 索引,但 status 和 create_time 过滤在回表后执行。
  • filesort 因为 create_time 没在索引中用于排序。

优化方案:建立联合索引 (customer_id, status, create_time)。

新执行计划:type=ref,key=联合索引,key_len=4+?+3,Extra=无 filesort(因为索引已排序)。

效果:查询从 0.5 秒降到 0.02 秒。


七、总结与实用检查清单

阅读 EXPLAIN 时按以下顺序检查:

  1. type:是否出现了 ALL 或 index?如果是,考虑加索引。
  2. key:是否为 NULL?是则索引没用上。
  3. rows:是否远大于预期?检查索引选择性。
  4. Extra:是否出现 Using temporary 或 Using filesort?优化排序和分组。
  5. filtered:是否低于 30%?检查索引是否能覆盖更多过滤条件。

小耶在手,SQL 不愁

还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽……我们下次见~

相关文章
|
3月前
|
存储 人工智能 弹性计算
AgenticFS 重磅发布:专为 AI Agent 打造的全新文件存储
阿里云发布AgenticFS——全球首款Agent Native文件存储,专为AI Agent场景设计。单系统支持百万级AgenticSpace,提供目录级权限隔离、独立配额与性能QoS,峰值挂卸载达10万QPS,兼顾安全、弹性与超大规模扩展能力。(239字)
677 118
|
3月前
|
人工智能 编解码 数据可视化
阿里云国际站代理商:GPU 选型避坑指南 2026 大模型训练与推理算力配置
本文聚焦2026年AI多模态时代GPU选型实战。针对训练、推理、渲染三大场景,详解gn8v(H100/H200)、gn8is(L20)、gn7i(A10)等主流实例的适用性与性价比,并提醒账号风控、配额限制、地域库存等关键避坑点。(239字)
|
3月前
|
人工智能 IDE 开发工具
Qoder CLI 启动命令更新为 qoder
Qoder CLI 自V1.1.18起支持直接输入`qoder`启动(国际版)或`qodercn`(中国版),原命令仍兼容。它既是轻量CLI工具,也是AI编程智能体,可自主读码、改文件、执行验证,并支持CI/CD集成与SDK企业定制。
549 0
|
4月前
|
人工智能 监控 API
‌阿里云百炼AI模型平台免费Tokens额度领取指南:问题解答、扣费及问题解答FAQ
阿里云百炼新用户开通即赠超7000万Tokens,70+主流模型各享100万免费额度(限中国内地版,有效期90天),仅支持实时推理调用。在阿里云百炼官网:https://t.aliyun.com/U/fPVHqY 免费领取千万Tokens
|
5月前
|
SQL Java 关系型数据库
【Spring全家桶】Spring Cloud 2023.0.x:分布式事务:Seata 四大模式(AT/TCC/SAGA/XA)、适用场景(附《思维导图》+《面试高频考点清单》)
本文系统梳理Spring Cloud 2023.0.x(Leyton)与Seata分布式事务的深度集成,涵盖AT/TCC/SAGA/XA四大模式原理、多维对比、场景选型及高可用实践,助力微服务数据一致性落地。
1271 5
【Spring全家桶】Spring Cloud 2023.0.x:分布式事务:Seata 四大模式(AT/TCC/SAGA/XA)、适用场景(附《思维导图》+《面试高频考点清单》)
|
3月前
|
人工智能 IDE 搜索推荐
阿里云Qoder CN原名通义灵码指南及收费价格,个人社区版免费使用哦
阿里云Qoder CN(原通义灵码)是面向开发者的AI智能编码助手,支持VS Code、JetBrains等IDE插件及独立IDE,覆盖代码补全、问答、Agent、RepoWiki等场景,提供多模型(Qwen/GLM/Kimi)支持与灵活计费版本。阿里云Qoder CN官网:https://t.aliyun.com/U/fEiOLV
|
4月前
|
人工智能 弹性计算 运维
阿里云轻量应用服务器2核2G抢购38元1年、2核4G199元1年,云服务器99元1年区别与选购指南参考
阿里云2026年特惠活动推出多款高性价比云服务器:新用户可抢轻量应用服务器,2核2G仅38元/年(每日10点/15点限量),2核4G低至9.9元/月或199元/年,支持WordPress、OpenClaw AI、Hermes智能体等镜像一键部署;新老用户同享经济型e实例,2核2G固定3M带宽99元/年,续费同价可锁定至2030年。此外,通用算力型u2i实例年付3折,第九代企业级ECS(c9i/g9i/r9i)6.4折起,覆盖Web应用、AI推理、游戏服务器等场景。活动持续至2029年3月31日,是个人开发者与中小企业低成本上云的优质选择。
|
7月前
|
缓存 安全 算法
深入拆解 Java CAS:从底层原理到 ABA 问题实战
本文深入解析Java中CAS(比较并交换)的底层原理:从CPU指令级支持(cmpxchg、缓存锁/总线锁)、Unsafe类的核心作用,到ABA问题的成因及AtomicStampedReference等解决方案,全面剖析无锁并发机制的优劣与实践要点。
478 10
|
12月前
|
消息中间件 存储 Java
企业实战RocketMQ:从API到架构开发的深度解析与落地实践
本文全面介绍了Apache RocketMQ消息中间件的核心技术与实战应用。首先解析了RocketMQ的四大核心组件(NameServer、Broker、Producer、Consumer)及其底层逻辑,包括路由发现机制和三层存储结构。接着详细演示了环境搭建、API开发(普通/顺序/批量/事务消息)、企业级架构设计(高可用集群、消息可靠性保障)和幂等性处理方案。最后提供了常见问题排查方法和性能优化建议,涵盖Broker配置、生产消费优化等关键点。所有示例代码均经过生产验证,可直接应用于实际项目开发。
681 2
|
5月前
|
运维 Java 测试技术
程序员必备的十大技能(进阶版)之性能调优与故障排查(四)
教程来源 https://aescc.cn/ 本节系统介绍Java应用性能分析与稳定性保障核心实践:涵盖Arthas诊断、火焰图性能剖析、全链路压测方法论及JMeter实战、混沌工程故障注入(ChaosBlade),并复盘Full GC与数据库死锁两大典型故障案例,助力高效定位与解决线上性能问题。