show profile在mysql 8.0+中已被彻底移除,需改用performance_schema事件表(如events_statements_history_long和events_stages_history_long)配合启用consumers与instruments来定位sql各阶段真实耗时。

SHOW PROFILE 能暴露真实耗时阶段,但 8.0+ 默认不可用
MySQL 5.7 还能用 SET profiling = 1 + SHOW PROFILE FOR QUERY N 精准看到每个内部阶段耗时,比如 optimizing、statistics、Creating sort index;但 MySQL 8.0+ 已移除 profiling 功能,必须改用 performance_schema 中的事件表。
常见误操作是直接在 8.0 环境执行 SHOW PROFILES,结果报错或返回空——这不是配置问题,是功能已被删减。
- 8.0+ 正确路径:先确保
performance_schema开启(默认通常为 ON),再查performance_schema.events_statements_history_long或启用对应 consumers - 临时开启详细追踪(影响性能):
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'events%stage%'; - 查最近慢查询的阶段耗时:
SELECT EVENT_NAME, TIMER_WAIT FROM performance_schema.events_stages_history_long WHERE NESTING_EVENT_ID IN (SELECT EVENT_ID FROM performance_schema.events_statements_history_long WHERE SQL_TEXT LIKE '%your_slow_sql%') ORDER BY TIMER_WAIT DESC LIMIT 10;
EXPLAIN 的 rows 和 type 比 Query_time 更能说明卡点
很多人盯着 Query_time: 2.345s 发愁,其实真正该看的是 EXPLAIN 输出里那三列:type、key、rows。它们直接反映优化器是否“走对了路”。
-
type = ALL或index:说明没走有效索引,大概率卡在“全表扫描”或“索引覆盖扫描”,不是解析慢,是读数据慢 -
key = NULL:铁定没用索引;key非空但type仍是ALL,往往是复合索引没满足最左前缀,比如索引是(a,b,c),而条件只写了WHERE b = 1 -
rows显示 100 但实际耗时 2s:说明统计信息严重失真,优化器误判了成本——这时真正卡点在statistics阶段,该跑ANALYZE TABLE table_name
SHOW PROCESSLIST 看实时状态,Copying to tmp table 是强信号
当 SHOW PROCESSLIST 中某条语句状态长期卡在 Copying to tmp table 或更糟的 Copying to tmp table on disk,基本可断定:中间结果集太大,内存撑不住,被迫落盘。
- 先确认是否落盘:
SHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables';对比前后增长量 - 查内存限制:
SELECT @@tmp_table_size, @@max_heap_table_size;二者取小值,就是单查询能用的最大内存临时表容量 - 别急着调大
tmp_table_size:90% 的场景,根本解法是加索引,让GROUP BY、ORDER BY、JOIN能走索引有序性,避免生成临时表——比如ORDER BY gmt_modified DESC就该有INDEX(gmt_modified)
optimizer_switch 关闭 condition_fanout_filter 可快速验证优化阶段卡顿
MySQL 8.0+ 默认开启 condition_fanout_filter=on,遇到多表 JOIN + 复杂 WHERE 时,可能反复回表估算行数,把大量时间耗在 optimizing 阶段,表现为简单 SELECT 执行时间波动大、EXPLAIN 显示 rows 远超实际。
- 临时关闭验证:
SET optimizer_switch='condition_fanout_filter=off';,再跑一次慢 SQL,对比耗时变化 - 如果耗时明显下降,说明确实是代价模型误判导致卡在优化阶段,而非数据层问题
- 注意:这只是诊断手段,不能长期关闭;长期解法是更新统计信息(
ANALYZE TABLE)或补充直方图(ANALYZE TABLE t UPDATE HISTOGRAM ON c)
EXPLAIN 的 rows 和 SHOW PROCESSLIST 的状态里,而不是日志里的 Query_time 数字——数字只告诉你“慢了”,这两者才告诉你“为什么慢”和“卡在哪”。











