
聚焦 MySQL 面试里的执行计划追问,用 key、key_len、rows、filtered 4 个字段串起 EXPLAIN 与 EXPLAIN ANALYZE,给出可复述的排查顺序和避坑清单。
key 有没有值」,很容易被继续追问:用了联合索引的哪一段?rows 是真实扫描行数吗?Using filesort 就一定要加索引吗?EXPLAIN 和 EXPLAIN ANALYZE,用 key、key_len、rows、filtered 4 个字段先读懂优化器的估算,再用实际执行结果校验。这样回答不会停在口诀,而是能落到「计划是什么、估算准不准、下一步查哪里」。EXPLAIN 不会执行查询,它展示优化器准备采用的执行计划。EXPLAIN ANALYZE 会实际执行语句,并把估算的行数、时间与真实返回行数、循环次数放在执行树里,适合检查估算和实测是否偏离。2我先用EXPLAIN看访问路径和估算,再用只读的EXPLAIN ANALYZE验证估算是否接近真实执行;因为后者会执行查询,生产环境不能直接对任意语句使用。
KEY idx_user_status_time (user_id, status, created_at)SELECT id, status, created_at
FROM orders
WHERE user_id = 42
AND status = 'PAID'
AND created_at >= '2026-01-01'
ORDER BY created_at DESC
LIMIT 20;EXPLAIN
SELECT id, status, created_at
FROM orders
WHERE user_id = 42
AND status = 'PAID'
AND created_at >= '2026-01-01'
ORDER BY created_at DESC
LIMIT 20;EXPLAIN ANALYZE
SELECT id, status, created_at
FROM orders
WHERE user_id = 42
AND status = 'PAID'
AND created_at >= '2026-01-01'
ORDER BY created_at DESC
LIMIT 20;key:实际用了哪一个索引key 是否为 idx_user_status_time?key 为 NULL,是否缺少合适索引,或者优化器判断走索引不划算?possible_keys 有值但 key 不同,实际选中的路径是什么?possible_keys=idx_user_status_time 就回答「已经走联合索引」。正确表述是:possible_keys是候选集合,key才是实际选中的索引。我先确认真正的访问路径,再解释为什么选它。
key_len:联合索引实际用了多深(user_id, status, created_at)key_len 的一个数字,脱离表结构直接说「用了前两列」。更稳的现场步骤是:SHOW CREATE TABLE orders,确认 3 列的数据类型、字符集和 NULL 属性。key_len 与每一列的索引长度相加结果对照。WHERE 条件判断,是等值条件连续命中,还是在某个范围条件处停止了深入匹配。(col1, col2, col3) 可以支持 (col1)、(col1, col2) 和完整三列这样的左侧连续前缀;只查 (col2) 或 (col2, col3),不能作为索引查找的左侧前缀。3能否用于定位,取决于查询条件是否形成索引定义的左侧连续前缀;key_len用来辅助确认实际深入了多少。
rows:优化器预计要检查多少行rows 是优化器估算的、执行查询时需要检查的行数。对 InnoDB 来说它是估计值,不是真实计数。1rows=100000 时不要直接说「这条 SQL 扫了一万行」;应该说:计划阶段预计需要检查约 100000 行,真实执行量要用EXPLAIN ANALYZE对照。
rows 明显偏大,排查方向包括:key 和 key_len,否则你可能只是在一个没有真正使用的索引上继续堆列。filtered:剩下多少比例能通过表条件filtered 是表条件过滤后的估算百分比。比如 rows=1000、filtered=10.00,可以粗略理解为约有 1000 × 10% = 100 行进入后续连接;单表查询则可以把它当作判断残余过滤量的线索。1key 正确、key_len 只用了前一部分,rows 很大、filtered 很低:可能先定位出一大片候选,再靠表条件过滤;key 正确、key_len 使用充分,rows 较小:计划阶段的候选范围更收敛;rows 估算很小,但 EXPLAIN ANALYZE 的实际行数很大:优化器估算可能失真,应该检查数据分布和统计信息,而不是直接把估算当事实。type 和 Extratype 是否符合数据量和查询场景?key 实际选了什么?key_len 说明联合索引用了多少,是否在范围条件处停止?rows 预计要检查多少,filtered 预计还剩多少?Extra 是否出现排序、临时表或其他需要验证的处理?EXPLAIN ANALYZE 看估算与真实行数、时间、循环次数是否一致。EXPLAIN 验证,而不是只看建表语句或索引名称。4我会先看type和key,确认访问方式以及实际使用的索引;再看key_len,结合表结构判断联合索引用了哪些前缀。然后看rows和filtered,区分优化器预计检查多少候选行、过滤后还剩多少。最后看Extra是否有额外排序或临时表。普通EXPLAIN只是估算计划,我会在安全的只读环境用EXPLAIN ANALYZE做实测,比较估算行数和实际行数,再决定是检查统计信息、调整索引顺序,还是改写查询。
key 有值,就说「索引没问题」key_len、rows、filtered 和 Extra。key_len 变大,就说「一定更快」key_len 是解释计划的证据,不是性能承诺。rows 当成监控里的真实扫描量Using filesort 当成唯一结论EXPLAIN ANALYZE 的实测结果。type、key、key_len、rows、filtered、Extra 当前是什么;EXPLAIN ANALYZE 后,实际行数和时间是多少;dev.mysql.com
dev.mysql.com
dev.mysql.com
dev.mysql.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.