能,但需 performance_schema 启用且 sys 库已安装;验证方式:SHOW VARIABLES LIKE 'performance_schema' 返回 ON,且 SELECT COUNT(*) FROM sys.version 可查出版本号。

能,但前提是 performance_schema 已启用且 sys 库已安装 —— 否则 sys.statement_performance_analyzer() 会直接报错 PROCEDURE sys.statement_performance_analyzer does not exist。
确认 performance_schema 和 sys 库是否就绪
很多问题其实卡在第一步:你以为它开着,其实没开。执行这两条命令是最快验证方式:
-
SHOW VARIABLES LIKE 'performance_schema';—— 必须返回ON,否则sys库所有函数都不可用 -
SELECT COUNT(*) FROM sys.version;—— 能查出版本号(如5.8.31)说明sys库已正确初始化;若报错Unknown table 'sys.version',需手动安装:mysql -u root (路径依 MySQL 安装方式而异) - 注意权限:执行
sys存储过程需要EXECUTE权限,不是只给SELECT就够的
用 sys.statement_performance_analyzer() 抓取增量快照
这个存储过程本质是“拍两张照片再比差异”,不是实时流式分析。它只对 events_statements_summary_by_digest 表起作用,所以必须确保该表的消费者已启用:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 先检查:
SELECT * FROM performance_schema.setup_consumers WHERE NAME = 'events_statements_digest';——ENABLED列必须为YES - 调用示例:
CALL sys.statement_performance_analyzer('snapshot', NULL, NULL);拍第一张快照;等 30–60 秒(覆盖业务高峰或压测窗口),再执行一次 - 生成报告:
CALL sys.statement_performance_analyzer('overall', NULL, NULL);—— 这会输出按总延迟排序的 Top SQL 摘要,含DIGEST_TEXT、avg_timer_wait、sum_rows_affected等关键列 - 别用
'detailed'模式查生产库:它会关联大量历史事件表,可能拖慢 performance_schema 本身,尤其在高并发场景下
为什么 sys.statement_performance_analyzer() 的结果里看不到具体 SQL?
因为 sys 库默认只存 DIGEST(哈希摘要),不存原始语句文本 —— 这是性能与隐私的权衡。想还原真实 SQL,得手动查:
-
SELECT DIGEST_TEXT FROM performance_schema.events_statements_summary_by_digest WHERE DIGEST = 'xxx...';(把报告里的DIGEST值粘贴进去) - 但注意:如果
performance_schema.events_statements_history_long未启用或已满,这条语句可能查不到上下文;更稳妥的方式是配合慢查询日志交叉验证 - 常见陷阱:同一条 SQL 因参数不同(比如
WHERE id = 1vsWHERE id = 2)会被归为不同DIGEST,导致“高频小查询”被拆散,漏掉真正的问题模式
报告里 avg_timer_wait 很低但 count_star 极高,意味着什么?
这是典型的“隐形杀手”:单次不慢,但执行频率太高,吃光 CPU 或锁资源。这时候不能只看平均值,要重点看:
-
sum_timer_wait:总耗时,决定它是否真占资源大头 -
sum_lock_time:高并发下,哪怕每次只锁几毫秒,百万次累积也能阻塞其他事务 -
sum_rows_examined:如果远大于sum_rows_sent,说明有大量无效扫描,索引可能失效或缺失 - 别急着加索引:先用
EXPLAIN FORMAT=JSON查这个DIGEST_TEXT对应的执行计划,确认type是ALL还是range,避免盲目优化
真正容易被忽略的是时间窗口的匹配精度 —— 如果两次 snapshot 之间没覆盖到实际慢查询发生的那几秒,报告就是空白的。建议搭配 SHOW PROCESSLIST 或 performance_schema.events_waits_current 实时抓取正在等待的线程,补上快照的盲区。


















