events_statements_summary_by_digest是聚合统计表,按DIGEST归一化分组,持续累加执行指标;它不依赖历史表容量、不易被覆盖、数据长期存在,适合定位反复慢的SQL,比events_statements_history_long更可靠。

直接查 events_statements_summary_by_digest 表,按平均耗时排序,是最快、最稳的方式。它不依赖历史表容量,也不怕被覆盖,适合快速定位“反复慢”的 SQL。
为什么不用 events_statements_history_long 查“当前最慢”
这个表默认只存 10000 行,按插入时间倒序覆盖;一旦负载高,刚执行完的慢 SQL 可能立刻被新语句挤掉。更麻烦的是:如果 setup_consumers 没开对(比如 events_statements_history_long 被设为 DISABLED),查出来就是空——你却以为没慢 SQL,实际只是没采集到。
常见错误现象:
– 执行 SELECT 查询返回 0 行或全是 NULL
– DIGEST_TEXT 字段大量为 NULL
– 同一条 SQL 在 SHOW FULL PROCESSLIST 里卡着不动,但在 history 表里找不到
原因基本就两点:
– consumers 里对应项没启用:UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_statements_history_long';
– instruments 粒度太粗:UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'statement/sql/%';
– 改完必须执行 FLUSH STATUS;,否则旧缓存还在用
events_statements_summary_by_digest 是什么,为什么更可靠
这张表是聚合统计表,不是历史快照。它把所有归一化后的 SQL(比如 SELECT * FROM users WHERE id = 123 和 SELECT * FROM users WHERE id = 456 都变成 SELECT * FROM users WHERE id = ?)按 DIGEST 分组,持续累加执行次数、总耗时、最大/最小/平均耗时等指标。
关键优势:
– 不受内存容量限制,数据长期存在(除非手动 TRUNCATE)
– 即使某条 SQL 刚执行完就结束,只要它被 instrumented 过,就会进统计
– AVG_TIMER_WAIT 直接反映“每次执行多慢”,比单次毛刺更有业务意义
查法示例:SELECT DIGEST_TEXT, COUNT_STAR, SUM_TIMER_WAIT / 1000000000000 AS sum_sec, AVG_TIMER_WAIT / 1000000000000 AS avg_sec FROM performance_schema.events_statements_summary_by_digest WHERE DIGEST_TEXT IS NOT NULL AND DIGEST_TEXT NOT LIKE 'SELECT DIGEST%' ORDER BY AVG_TIMER_WAIT DESC LIMIT 10;
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
注意:
– TIMER_WAIT 单位是皮秒(10⁻¹² 秒),务必除以 1000000000000 转成秒,别错看成毫秒
– 过滤掉 SELECT DIGEST% 是为了排除 performance_schema 自身查询干扰
– 如果 COUNT_STAR 很小但 AVG_TIMER_WAIT 极高,说明是偶发性大查询,得结合应用日志看触发场景
查之前必须确认的三件事
哪怕 MySQL 5.7+ 默认开启 performance_schema,也常因环境差异失效:
– 执行 SELECT @@performance_schema;,返回 1 才算真正启用
– 执行 SELECT COUNT(*) FROM performance_schema.setup_instruments WHERE ENABLED = 'YES' AND NAME LIKE 'statement/sql/%';,结果应 > 0(至少几十行)
– 执行 SELECT * FROM performance_schema.setup_consumers WHERE ENABLED = 'YES';,确保 statements_digest 和 events_statements_current 至少有一项是 YES
漏掉任意一项,events_statements_summary_by_digest 就可能为空或严重缺失数据。Docker 镜像、阿里云 RDS 低配版、腾讯云 CVM 上的 MySQL 常默认关掉部分 instruments,不能只信“默认开启”四个字。
真正的难点不在 SQL 怎么写,而在于确认采集链路每个环节都通——instrument 开了没、consumer 接收了没、单位换算对没、干扰语句滤干净没。少一步,看到的就是假安静。










