这组计数看什么
MySQL 的 Handler 与 InnoDB 状态计数从扫描行为侧面反映查询是怎么读数据的:按索引键定位、按索引顺序扫描、还是全表逐行读。它不能告诉你哪条 SQL 慢,但能在 EXPLAIN 之外给出「实际读了多少行」的证据——前提是用两次快照的差值来判断。
基本信息
| 适用平台 | MySQL(SHOW GLOBAL STATUS 或 performance_schema.global_status) |
|---|---|
| Handler_read_key | 按索引键定位的读取次数 |
| Handler_read_next | 按索引顺序读下一行(范围或索引扫描) |
| Handler_read_rnd_next | 全表顺序读下一行,持续增长提示表扫描 |
| Innodb_rows_read | InnoDB 读取行数总量 |
| 判读方法 | 取两次快照做差,绝对值没有意义 |
典型使用场景
- 验证某条查询到底是走索引还是扫全表
- 压测或跑批前后对比扫描量增量
- 排查周期性任务是否引入了全表扫描
- 解释「计划说走索引、实际却很慢」的差异
- 长期监控全表扫描趋势,指导加索引
取数与对比
取数与对比
SHOW GLOBAL STATUS
WHERE Variable_name IN ('Handler_read_first','Handler_read_key',
'Handler_read_next','Handler_read_rnd_next','Innodb_rows_read','Queries');
-- 也可以用 performance_schema 过滤同一组变量
SELECT VARIABLE_NAME, VARIABLE_VALUE
FROM performance_schema.global_status
WHERE VARIABLE_NAME LIKE 'Handler_read%'
OR VARIABLE_NAME = 'Innodb_rows_read';
-- 压测或跑批前后各取一次快照,用差值判断扫描量计数逐项读法
| 计数 | 统计什么 | 异常信号 |
|---|---|---|
| Handler_read_key | 按索引键定位的次数 | 远低于扫描次数说明索引没被用上 |
| Handler_read_next | 按索引顺序读下一行 | 结合范围条件判断扫描区间大小 |
| Handler_read_rnd_next | 全表顺序读下一行 | 持续增长说明在做表扫描 |
| Innodb_rows_read | InnoDB 读取行数总量 | 与返回行数差距大说明读了多余数据 |
| Queries | 执行的语句总数 | 用来把增量归一化成每次查询的量 |
这些都是自启动以来的累计值:判断「现在是否在扫表」要看两次快照的差值,绝对值大可能只是很久以前跑过一次批量任务。
Handler_read_rnd_next 只统计行读取动作,不代表磁盘 IO:是否命中缓冲池要看 InnoDB 的物理读计数,两套指标要分开解读。