rows_examined 远大于 rows_sent 是引擎层低效的明确信号,表明大量io和cpu被浪费在无效行扫描上,主因是索引未命中、失效或全表/全索引扫描。

Rows_examined 远大于 Rows_sent 是最典型的引擎层低效信号,不是“可能慢”,而是“已经浪费了大量IO和CPU”。
为什么 Rows_examined 高就代表引擎性能差
MySQL 在执行查询时,Rows_examined 是存储引擎实际读取并评估的行数(包括回表、索引扫描、临时表遍历等),而 Rows_sent 是最终返回给客户端的行数。两者比值悬殊(比如 100000:1)说明:绝大部分扫描动作都白做了——要么没走对索引,要么索引失效,要么用了全表扫描或全索引扫描。
这和应用层响应时间无关,是纯粹的存储引擎执行效率问题:InnoDB 要反复定位、读取、解压、判断行是否满足条件,每一行都消耗 buffer pool、磁盘IO 和 CPU cycles。
- 常见诱因:
WHERE条件未命中索引前缀、LIKE '%xxx'导致索引失效、隐式类型转换(如字符串字段 vs 数字值)、函数包裹索引列(WHERE YEAR(create_time) = 2025) - 容易被忽略的点:
ORDER BY或GROUP BY引发的 filesort 或临时表,也会显著推高Rows_examined,即使WHERE很快 - 注意区分:
Rows_examined高 ≠ SQL 写得烂,也可能是数据分布突变(如某天突然出现大量空值/默认值,导致索引选择性暴跌)
从慢日志里快速定位高 Rows_examined 查询
不要人工翻日志。用 mysqldumpslow 或直接 grep 提取关键指标:
mysqldumpslow -s ar -t 10 /var/log/mysql/slow.log
其中 -s ar 表示按 Rows_examined 总和排序(a=average, r=Rows_examined),-t 10 取前10条。输出中会带 Rows_examined 和 Rows_sent 的统计值。
如果日志格式是标准文本(非 JSON),也可用 awk 快速筛出比值 > 100 的条目:
awk '/Rows_examined:/ && /Rows_sent:/ {r=$3; s=$6; if(r/s > 100) print}' /var/log/mysql/slow.log | head -20
- 确认日志是否记录了这些字段:检查
log_output是否为file(不是table),且 MySQL 版本 ≥ 5.6.5;Rows_examined在 5.7+ 默认开启,5.6 需确保long_query_time设为 0 才能捕获所有扫描开销大的语句 - 避免误判:单次
Rows_examined=1000不一定有问题,要看业务场景——分页查第100页(LIMIT 9990,10)天然高扫描,但这是设计使然;真正危险的是WHERE id = ?却扫了 5 万行
验证是否真由引擎行为导致 —— 看 EXPLAIN 的 rows 列
EXPLAIN 输出中的 rows 字段,就是优化器预估的 Rows_examined。它和慢日志里的实测值应基本一致(误差在 20% 内)。如果不符,说明统计信息过期或执行计划发生了变化。
重点看这几项:
-
type是ALL或index:基本等于全表/全索引扫描,立刻检查WHERE条件能否走索引 -
key为NULL:明确表示没用上索引,哪怕表上有索引 -
Extra含Using filesort或Using temporary:意味着排序或聚合没走索引,Rows_examined会包含中间结果集的遍历 - 对比
rows和实际表行数:rows接近SHOW TABLE STATUS LIKE 't'的Rows值,就是典型全扫
例如执行 EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = 'paid',若 rows=85234 而表总行数才 9 万,说明这个复合条件没走有效索引,需要建 (user_id, status) 联合索引。
Rows_examined 高但查询不慢?先别高兴
一种典型假象:某查询 Rows_examined=50000,但耗时仅 0.02 秒。看起来“很快”,其实隐患更大——它大概率靠 buffer pool 缓存“蒙混过关”。一旦缓存淘汰、数据量翻倍或并发上升,延迟立刻飙升。
更危险的是这种查询往往被业务代码反复调用(如用户中心页每次加载都查一次),把原本分散的 IO 压力集中到同一组页上,极易引发 buffer pool 争用、page clean 延迟、甚至刷脏页阻塞。
所以不要只盯 Query_time,Rows_examined 是比耗时更早、更稳的性能退化探测器。只要它异常升高,就该立刻用 EXPLAIN 定位,而不是等用户投诉页面卡顿。











