首页/数据/SQL 速查/rows 与 filtered 估算解读
性能与执行计划72 条

rows 与 filtered 估算解读

rows 是预估扫描行数、filtered 是过滤后剩余百分比:两者相乘得到传给下一步的行数估算,用来定位低效过滤点。

SQL 速查数据更新于 2026-10-13

估算行数与过滤比例

在执行计划里,有一列表示「预计要扫描多少行」,另一列表示「过滤之后还剩百分之多少」。两者相乘,就是估算传给下一步的行数,也是优化器判断后续用嵌套循环还是哈希连接的主要依据。读这两个数的意义在于定位低效过滤:扫描几千行最后只留下几十行,说明大部分工作被浪费在读取与丢弃上,通常意味着过滤条件没能下推到索引层。

基本信息

适用平台MySQL 8.0(经典格式计划输出)
估算行数列预计扫描的行数,不是最终返回行数
过滤比例列以百分比表示过滤后剩余比例,范围零到一百
二者关系相乘得到传给下一步的估算行数
前置动作统计信息陈旧时先重新采样再对比

典型使用场景

  • 连接变慢:确认驱动侧产出的估算行数是否被高估或低估
  • 索引评估:判断过滤列该不该加进复合索引
  • 参数化差异排查:同一语句不同参数的计划差异是否来自过滤比例
  • 改写验证:改写后对比估算与实际行数的接近程度
  • 优化决策留痕:把计划前后对比记录进变更文档

读取与更新统计

读取与更新统计
-- 查看计划中的估算行数与过滤比例
EXPLAIN SELECT * FROM orders
WHERE user_id = 100 AND status = 'paid';
-- 假设输出显示:扫描行数 500,过滤比例 10.00
-- 含义:预计扫 500 行,过滤后约剩 50 行传给下一步

-- 统计信息陈旧时先刷新再对比,避免在旧估算上做决策
ANALYZE TABLE orders;
EXPLAIN SELECT * FROM orders
WHERE user_id = 100 AND status = 'paid';

-- 需要真实执行数据时用分析模式(会真实执行语句)
-- EXPLAIN ANALYZE SELECT ... ;

-- 想让过滤在索引层完成,把过滤列加入复合索引后复看计划
-- ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);

两列读法

观察项含义异常信号
估算行数预计扫描行数与真实行数差一两个数量级
过滤比例过滤后剩余百分比数值很低说明大量行读完即丢
两者乘积传给下一步的估算行数偏大时后续可能被选中较重的算法
索引使用列实际选择的索引显示未使用索引说明条件不匹配
额外信息列排序、下推等提示出现临时表说明中间结果偏大
过滤比例是一个百分比,不是行数:显示百分之十意味着大约剩下十分之一的行,误解成十行会把估算规模判断错一个量级。
估算行数是基于统计信息的推测,数据分布倾斜严重或统计信息过期时偏差很大。判断优化效果时要把估算与实际放在一起看,只看估算容易得出相反结论。

易错点

  • 把过滤比例当成行数读,估算规模判断错一个量级,后续分析全盘偏移
  • 统计信息过期时直接下优化结论,可能优化了一个本来就不是瓶颈的地方
  • 只看估算行数不看实际行数,忽略统计信息失真带来的误导
  • 给过滤列加索引时不看列顺序,复合索引前导列选错,索引仍无法用于该查询
  • 忽略计划中的额外信息列,漏掉排序与临时表这类更明显的瓶颈信号

数据来源与参考

  • MySQL 8.0 Reference Manual §8.8.2 EXPLAIN Output Format(rows、filtered)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌