需先确认performance_schema已启用且instrumentation全开:检查@@performance_schema=1,启用statement/sql/%类采集器和events_statements_current/history消费者,再查对应表获取微秒级耗时。

怎么确认 performance_schema 真正在记录 SQL 耗时
别一上来就查表,先看基础是否就位。很多情况下你查 events_statements_current 是空的,不是语句没跑,而是 instrumentation 没开全。
必须逐项确认:
-
SELECT @@performance_schema;返回 1 才算启用成功 -
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE 'statement/sql/%';—— 不开这个,所有 SQL 都不会被计时 -
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('events_statements_current', 'events_statements_history');—— 消费者关了,数据生成了也看不到 - 如果只关心当前会话,建议用
CONNECTION_ID()锁定线程,避免被其他连接干扰
查单条 SQL 的实时微秒耗时:用 events_statements_current
这条语句还没结束时,它只存在 events_statements_current 里,且 TIMER_WAIT 是纳秒单位,要除以 1000000000 才是秒,除以 1000 才是毫秒,除以 1 就是纳秒——你要微秒级,就除以 1000。
典型查询:
SELECT THREAD_ID, SQL_TEXT, TIMER_WAIT/1000 AS time_us FROM performance_schema.events_statements_current WHERE SQL_TEXT IS NOT NULL AND CURRENT_SCHEMA = 'your_db' AND THREAD_ID = (SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID = CONNECTION_ID());
注意:TIMER_WAIT 在语句刚进入执行阶段时才开始累计,prepare、parse、optimize 这些前置阶段不计入;如果返回 NULL,说明语句还没真正执行(比如卡在 waiting for lock),或已被清理。
为什么 events_statements_current 查不到刚执行完的语句
它只存“正在执行”的快照,语句一结束就清空。想查刚跑完的,得切到 events_statements_history 或 events_statements_history_long。
但要注意:
-
events_statements_history默认每线程只存 10 条,容易被覆盖 -
events_statements_history_long默认关闭,需手动开启 consumer:UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_statements_history_long'; - 查历史语句时,
TIMER_WAIT是最终总耗时,但无法回溯各 stage(如executing、sending data)的分段耗时——stage 级数据默认只存在events_stages_current中,且不持久化
微秒级耗时不准?先盯住这几个坑
哪怕配置全开,你看到的数字也可能和应用层对不上,这不是 bug,是设计使然:
-
TIMER_WAIT只统计 MySQL 内部“主动工作”时间,不包括:TCP 建连、包往返、客户端解析结果、操作系统调度延迟 - 锁等待(如
Waiting for table metadata lock)在events_statements_current里可能显示为TIMER_WAIT = 0或极小值,真实等待被归入events_waits_current,得另查 - 预编译语句(
PREPARE/EXECUTE)的耗时会被拆到 prepare 阶段和 execute 阶段,单独查EXECUTE会漏掉 parse 和 optimize 时间 - MySQL 8.0.22+ 已弃用 profiling,但
performance_schema的计时逻辑仍受 server 层 tick 精度限制,极端场景下微秒位可能有 ±10μs 抖动
真要定位“为什么应用测出来 320ms,这里只显示 8ms”,优先查 performance_schema.events_waits_current 和 information_schema.INNODB_TRX,而不是反复刷新 events_statements_current。











