performance schema 默认不采集语句阶段耗时,需手动启用 stage instruments 和 consumers 并重连会话;查当前 stage 要通过 nesting_event_id 关联 events_statements_current 与 events_stages_current;分析整体耗时应使用汇总表如 events_stages_summary_by_thread_by_event_name。

Performance Schema 默认不采集语句阶段(如 parsing、optimizing、executing)的耗时数据,直接查 events_statements_current 或 events_stages_current 基本为空或 TIMER_WAIT 为 NULL——不是没执行,是根本没开采集。
必须手动启用 stage instruments 和对应 consumers
MySQL 启动后,stage/% 类监控器默认全为 DISABLED,哪怕 performance_schema 已启用。不改它,所有 stages 表都是空的。
- 立即生效(无需重启):
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE 'stage/%'; - 同时启用 consumer,否则数据不会写入表:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('events_stages_current', 'events_stages_history_long'); - 旧连接不继承新配置,必须重连或新建会话才生效
- 验证是否开启成功:
SELECT NAME, ENABLED, TIMED FROM performance_schema.setup_instruments WHERE NAME LIKE 'stage/sql/%' LIMIT 3;—— 输出中ENABLED和TIMED应均为YES
查当前卡在哪个 stage:必须用 NESTING_EVENT_ID 关联
events_stages_current 不是按 SQL 文本索引的,它只存“此刻线程正在执行的 stage”快照,且生命周期极短(语句一过就清空),直接 SELECT * 几乎总为空。
- 先定位活跃语句:
SELECT THREAD_ID, EVENT_ID, SQL_TEXT FROM performance_schema.events_statements_current WHERE SQL_TEXT LIKE '%UPDATE%'; - 再用返回的
THREAD_ID和EVENT_ID查对应 stage:SELECT EVENT_NAME, TIMER_WAIT/1E12 AS sec, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_current WHERE THREAD_ID = 42 AND NESTING_EVENT_ID = 123; - 如果查不到,说明语句已结束或进入 cleanup 阶段,此时应查
events_stages_history_long(需确保该 consumer 已启用) -
WORK_COMPLETED和WORK_ESTIMATED仅对部分 stage 有效(如stage/sql/sorting result、stage/innodb/alter table%),不是所有语句都支持
分析阶段耗时别翻 current 表,用 summary 表
想看某类操作(比如 sorting result)整体花了多少时间,不该依赖 events_stages_current 或 history_long——它们记录单次事件,样本易漏、聚合成本高。正确入口是汇总表。
-
events_stages_summary_by_thread_by_event_name按线程 + stage 类型统计总耗时(单位皮秒),适合定位瓶颈阶段:SELECT EVENT_NAME, SUM(TIMER_WAIT)/1E9 AS total_sec, COUNT_STAR FROM performance_schema.events_stages_summary_by_thread_by_event_name WHERE EVENT_NAME LIKE 'stage/sql/%' GROUP BY EVENT_NAME ORDER BY total_sec DESC LIMIT 5; - 该表数据是累积的,重启 MySQL 后清空;不依赖实时连接状态,比 current 表更稳定可靠
- 若要对比用户维度,可用
events_stages_summary_by_user_by_event_name,但需确认setup_actors中对应用户已启用HISTORY = 'YES'
最容易被忽略的一点:stage 数据不是“自动附着”在语句上的,它依赖 instrumentation 开启 + consumer 启用 + 新会话生效 + 正确嵌套关联四步缺一不可。少走一步,看到的就全是空值或 0。尤其注意旧连接不会自动更新配置,重连不是可选项,是必选项。











