Performance Schema 表级I/O监控需手动启用instrument:执行SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE 'wait/io/table%'确认ENABLED和TIMED均为YES,否则UPDATE启用;启用后通过table_io_waits_summary_by_table查COUNT_READ/COUNT_WRITE等指标,注意其统计的是存储引擎层物理访问次数而非SQL逻辑行数。

Performance Schema 能直接统计表级读写频率,但默认不开启表I/O事件采集,必须手动启用对应instrument。
如何确认表I/O监控是否已启用
Performance Schema 不是开箱即用的“全量监控”,table_io_waits_summary_by_table 这类表只有在对应 instrument 启用后才有数据。常见错误是查了空结果,却以为工具失效。
- 运行
SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE 'wait/io/table%';,检查ENABLED和Timed列是否都为YES - 若为
NO,需执行:UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME = 'wait/io/table/sql/handler'; - 注意:该修改仅对新连接生效,已有连接不会自动继承;重启 mysqld 可持久化,但更推荐在
my.cnf中配置performance_schema_instrument = 'wait/io/table/sql/handler=ON'
怎么查某张表的读写次数和耗时
启用后,performance_schema.table_io_waits_summary_by_table 就是核心视图。它按 OBJECT_SCHEMA 和 OBJECT_NAME 分组,聚合各类 I/O 事件。
- 读操作看
COUNT_READ、SUM_TIMER_READ(单位皮秒,除以 10^12 得秒) - 写操作看
COUNT_WRITE、SUM_TIMER_WRITE - 注意:
COUNT_FETCH是存储引擎层 fetch 行数,不是 SQL 层返回行数;COUNT_INSERT/COUNT_UPDATE/COUNT_DELETE才对应 DML 类型频次 - 示例:查
test.users表最近读写总量:SELECT OBJECT_SCHEMA, OBJECT_NAME, COUNT_READ, COUNT_WRITE, COUNT_INSERT, COUNT_UPDATE, COUNT_DELETE FROM performance_schema.table_io_waits_summary_by_table WHERE OBJECT_SCHEMA = 'test' AND OBJECT_NAME = 'users';
为什么 count_read 值远大于实际 SELECT 返回行数
这是最常见的误解点 —— Performance Schema 统计的是**存储引擎接口调用次数**,不是 SQL 层逻辑结果集大小。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 一次
SELECT * FROM t WHERE id > 100可能触发成百上千次handler::rnd_next(),每调用一次就累加COUNT_FETCH和COUNT_READ - 全表扫描、索引范围扫描、甚至某些优化器重写后的执行路径,都会显著放大底层 I/O 计数
- 所以它反映的是“物理访问压力”,不是“业务查询频次”。要统计 SQL 层执行次数,得结合
events_statements_summary_by_digest查COUNT_STAR - 如果只关心“这张表被哪些 SQL 频繁访问”,建议关联
events_statements_history_long+objects_summary_global_by_type做回溯分析
和慢查询日志、sys schema 比有什么区别
三者定位完全不同,混用反而容易误判。
-
slow_query_log只记录超阈值的语句,无法反映高频小查询带来的 I/O 累积压力 -
sys.schema_table_statistics是基于 Performance Schema 的封装视图,字段更友好,但底层仍是同一套数据源;它把COUNT_READ拆成了rows_fetched/rows_inserted等,语义更贴近应用层,但丢失了原始 timer 精度 - 直接查 Performance Schema 表的优势在于可过滤、可关联、可下钻到等待事件(比如发现某张表
SUM_TIMER_WAIT高,再查events_waits_summary_by_instance定位是磁盘 I/O 还是锁等待) - 代价是:内存占用略高(尤其高并发表多时),且需要理解 instrument 分层逻辑,否则容易查错视图
真正难的不是查出数字,而是判断这个 COUNT_WRITE 高到底是业务突增、缓存击穿、还是某段代码在循环里反复 update 同一行 —— 这时候得把 table_io_waits_summary_by_table 和 events_statements_summary_by_digest 的 DIGEST_TEXT 对上,才能闭环。










