因为events_statements_current只存“正在执行中”的语句快照,而stage级采集默认关闭,导致events_stages_current无数据,timer_wait常为null或极小值;必须手动启用stage instruments和consumer,且新会话才生效。

为什么直接查 events_statements_current 看不到实时耗时?
因为这张表只存“正在执行中”的语句快照,但默认情况下 stage 级采集是关着的,events_stages_current 里根本没数据。你看到的 TIMER_WAIT 往往是 NULL 或极小值,不是语句没跑,而是阶段事件压根没开采集。
必须手动启用 stage 相关 instruments 和对应 consumer:
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE 'stage/%';UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('events_stages_current', 'events_stages_history_long');- 改完立刻生效,无需重启,但旧连接不会自动继承——新会话或重连后才有效
events_stages_current 查不到数据?先确认线程和嵌套关系
即使开了采集,events_stages_current 也只记录当前正在执行的 stage,且依赖 NESTING_EVENT_ID 关联到父语句。直接 SELECT * 常常为空,是因为多数 DML(如 UPDATE)在 InnoDB 内部会拆成多个 stage,但只有“当前卡住的那个”留在 current 表里。
正确关联方式是:
- 先从
events_statements_current拿到活跃语句的THREAD_ID和EVENT_ID - 再用
WHERE THREAD_ID = ? AND NESTING_EVENT_ID = ?去events_stages_current查对应 stage - 注意:如果语句刚提交或已进入 cleanup 阶段,
events_stages_current可能已清空,得查events_stages_history_long
怎么算出“当前已执行多久”和“预估剩余时间”?
MySQL 8.0+ 对部分可估算操作(如 Filesort、Copying to tmp table)提供了 WORK_COMPLETED 和 WORK_ESTIMATED 字段,但仅限特定 stage 类型(如 stage/sql/sorting result),不是所有语句都支持。
实用查询示例:
SELECT stmt.SQL_TEXT, stage.EVENT_NAME, CONCAT(stage.WORK_COMPLETED, '/', stage.WORK_ESTIMATED) AS progress, (stage.TIMER_END - stmt.TIMER_START) / 1E12 AS elapsed_sec FROM performance_schema.events_statements_current stmt JOIN performance_schema.events_stages_current stage ON stage.THREAD_ID = stmt.THREAD_ID AND stage.NESTING_EVENT_ID = stmt.EVENT_ID WHERE stmt.SQL_TEXT IS NOT NULL;
注意:TIMER_END 为 NULL 表示 stage 还没结束;WORK_ESTIMATED = 0 表示无法估算,别硬除。
为什么 stage 耗时加起来 ≠ 语句总耗时?
Stage 是语句执行链路中的原子环节,但 MySQL 不保证覆盖全部路径。比如锁等待(wait/lock/table/sql/handler)属于等待事件,不在 stage 分类里;解析、优化等前端阶段也不进 stage 表,它们归在 statement 级别的 TIMER_WAIT 中。
真正反映端到端耗时的是 events_statements_current.TIMER_WAIT(单位纳秒),而 stage 耗时只是其中一部分。如果发现 stage 总和远小于语句总耗时,大概率卡在等待上——这时候该去查 events_waits_current 或 data_locks。
stage 数据默认不持久化,语句一结束就从 events_stages_current 消失,想回溯得提前开 events_stages_history_long 并确保容量够用(performance_schema_events_stages_history_long_size)。











