rows 是 mysql 优化器基于统计信息估算的扫描行数,非实际值;受统计更新、索引选择性、直方图及查询条件影响,需结合 type、key、Extra 综合判断性能问题。

rows 表示 MySQL 查询优化器预估的、为获取结果需要扫描或检查的行数,不是实际执行后的精确值,而是基于统计信息做出的估算。
rows 是估算值,不是真实扫描数
MySQL 在真正执行 SQL 前,会通过采样和统计信息(如索引基数、表总行数、直方图等)预测满足条件的数据量。这个预测值写在 rows 列中,用于指导优化器选择成本更低的执行路径(比如走全表扫描还是走某个索引)。它可能偏高或偏低,尤其在数据分布不均、统计信息过期、使用模糊查询(LIKE '%abc')或函数包裹字段(WHERE YEAR(create_time) = 2024)时,误差更明显。
- 全表扫描时,rows ≈ 表的总行数估计值(来自
mysql.innodb_table_stats) - 索引扫描时,rows ≈ 满足 WHERE 条件的索引记录条数估计值
- 如果
EXPLaiN显示 rows = 1,常见于主键 / 唯一索引等值查询(const或eq_ref类型)
影响 rows 准确性的关键因素
优化器无法“未卜先知”,它的估算依赖底层统计质量:
- 统计信息是否及时更新:执行
ANALYZE TABLE table_name;可手动刷新,避免因大批量写入后统计滞后导致误判 - 索引选择性(Cardinality)是否合理:基数越接近总行数,索引过滤能力越强;性别字段基数只有 2,优化器自然不太愿用它
- 是否有直方图(Histogram):MySQL 8.0+ 支持列级直方图,对非均匀分布字段(如订单金额、访问时间)能显著提升 rows 预估精度
- 查询条件是否可下推到存储引擎层 :带函数、 类型转换 、 隐式转换 的条件常导致优化器放弃使用索引统计,转而粗略估算
如何结合 rows 判断性能问题
单独看 rows 数值意义有限,需结合 type、key、Extra 综合判断:
- 若 type = ALL 且 rows 接近表总行数 → 很可能缺失有效索引,考虑添加或调整
- 若 type = range 但 rows 远大于实际返回行数 → 索引区分度差或条件写法不当(如用了前导通配符)
- 若 rows 很小但查询仍慢 → 关注 Extra 中是否出现
using filesort或Using temporary,说明排序 / 分组未走索引 - 对比加索引前后的 rows 变化:若加了索引后 rows 从 10 万降到 200,说明索引被有效利用
rows 和 filtered 的 区别
rows 是存储引擎层预估要读取的行数(即“找多少行”),而 filtered 是 Server 层预估这些行中最终满足 WHERE 条件的比例(百分比)。两者相乘 ≈ 最终返回给上层的行数(例如 rows=1000, filtered=10.00 → 预估 100 行满足条件)。注意:filtered 值低(如