SHOW PROFILE 的替代方案
SHOW PROFILE 与 SHOW PROFILES 在 MySQL 8.0 已弃用,且 profiling 会话变量默认关闭,用它做性能分析需要额外开启。官方给出的方向是 performance_schema 的阶段事件与 EXPLAIN ANALYZE:前者按解析、优化、执行、排序等阶段记录耗时,后者直接给出执行计划每个节点的实测行数与时间。
基本信息
| 适用版本 | MySQL 8.0 起弃用 SHOW PROFILE,profiling 默认关闭 |
|---|---|
| 替代一 | EXPLAIN ANALYZE(8.0.18 起)看计划各节点实测耗时 |
| 替代二 | performance_schema.events_stages_* 看解析优化执行阶段 |
| 替代三 | events_statements_* 与 sys 视图做语句级聚合排行 |
| 前置设置 | P_S 的 instruments 与 consumers 需按需开启 |
| 成本 | 采集范围越大开销越高,定位完要及时关闭 |
典型使用场景
- 定位单条慢 SQL 的时间究竟花在解析、优化还是执行阶段
- 对比改写前后同一语句各步骤的耗时变化
- 偶发慢查排查:在 P_S 历史表里按耗时倒序捞出目标语句
- 怀疑优化器估算偏差时用 EXPLAIN ANALYZE 看实测行数
- 把老运维脚本里的 SHOW PROFILE 改造成 8.0 可用版本
P_S 与 EXPLAIN ANALYZE
P_S 与 EXPLAIN ANALYZE
# 按需开启阶段采集(全域长期开启会增加开销)
UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES' WHERE NAME LIKE 'stage/%';
UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES' WHERE NAME LIKE 'events_stages%';
# 执行待分析语句
SELECT COUNT(*) FROM orders WHERE status = 'paid' AND created_at >= '2026-09-01';
# 阶段耗时:纳秒除以十亿换算成毫秒
SELECT EVENT_NAME, TIMER_WAIT/1000000000 AS ms
FROM performance_schema.events_stages_history_long
ORDER BY TIMER_WAIT DESC LIMIT 20;
# 8.0.18 起:一次看清计划各节点的实测值与估算值
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 42;
# 语句级聚合:先找最耗时的语句,再逐条深挖
SELECT DIGEST_TEXT, COUNT_STAR, AVG_TIMER_WAIT/1000000000 AS avg_ms
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;手段与适用场景
| 手段 | 能看什么 | 适用场景 |
|---|---|---|
| EXPLAIN ANALYZE | 计划各节点的实测行数与耗时 | 单条查询深挖 |
| P_S stages 表 | 阶段名与耗时 | 区分解析、优化、执行瓶颈 |
| P_S statements 表 | 按语句摘要聚合统计 | 全库热点排行 |
| sys 视图 | statement_analysis 等易读视图 | 日常巡检 |
| SHOW PROFILE | 已弃用且默认关闭 | 仅老版本兼容沿用 |
更省事的排查顺序是先看 sys 视图或 events_statements_summary_by_digest 找出最耗资源的语句,再对那一条用 EXPLAIN ANALYZE 深挖;阶段级采集只在需要区分解析、优化、执行耗时时才开。