SHOW PROFILE仅适用于MySQL 5.7及更早版本且需SET profiling=1开启,结果仅限当前会话、按执行顺序覆盖,关键看handler_read_next、Creating sort index、Copying to tmp table等阶段占比定位索引与排序瓶颈。

确认 MySQL 版本和 profiling 开关状态
SHOW PROFILE 只在 MySQL 5.7 及更早版本中可用,且默认关闭。执行前必须验证两点:SELECT VERSION() 返回 5.7.x(或更低),且 SELECT @@profiling 返回 1。
常见错误是只查 @@have_profiling —— 它只表示编译时支持,不等于当前可用。如果返回 0,需立即执行:SET profiling = 1。注意:该设置仅对当前会话有效,新开连接要重设。
另外,SELECT @@profiling_history_size 默认为 15,若中间执行了大量语句,目标 SQL 的 Query_ID 可能已被覆盖,查不到数据。
执行 SQL 后立刻查 profile,别等、别缓存
SHOW PROFILE 查的是“上一条”语句(或指定 FOR QUERY n),不是预估计划,也不是历史快照。一旦你执行了其他语句,之前的 profile 就被覆盖。
正确顺序必须是:
- 先执行
SET profiling = 1 - 紧接着执行目标 SQL(例如:
SELECT * FROM orders WHERE status = 'paid' ORDER BY created_at DESC LIMIT 100) - 马上执行
SHOW PROFILES找到对应Query_ID - 再执行
SHOW PROFILE FOR QUERY n(n 是刚查到的 ID)
不要加 EXPLAIN 再跑一次——它不触发 profiling;也不要“简化”语句去分析,比如删掉 ORDER BY 或 LIMIT,那得到的阶段耗时和真实场景完全脱节。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
盯住这几个 Status 行,它们暴露索引与排序的真实瓶颈
总耗时没意义,关键看各阶段占比。以下三项最能反映 SQL 是否高效利用索引:
-
handler_read_next:B+Tree 索引逐行扫描次数。值越大,说明索引过滤性差(如前缀索引匹配低、WHERE 条件选择率低) -
Creating sort index:MySQL 在内存或磁盘建排序结构。出现即表明ORDER BY字段未被联合索引覆盖,或索引顺序不匹配 -
Copying to tmp table:隐式临时表被触发(常见于GROUP BY、DISTINCT、UNION)。即使走了索引,也可能因无法覆盖所有查询字段而被迫回表+建表
如果 statistics 阶段耗时异常高,大概率是统计信息过期,应运行 ANALYZE TABLE;如果 Waiting for query cache lock 占比明显,直接关掉 query cache 更稳妥:SET GLOBAL query_cache_size = 0。
CPU 和 IO 细节要用对参数,别默认 ALL
SHOW PROFILE 默认输出所有阶段的 wall-clock 时间,但 CPU 和 IO 消耗需要显式指定参数才能看到。比如:
-
SHOW PROFILE CPU FOR QUERY 2:显示用户态和内核态 CPU 时间(CPU_user/CPU_system) -
SHOW PROFILE BLOCK IO FOR QUERY 2:显示块读写次数(Block_ops_in/Block_ops_out) -
SHOW PROFILE CONTEXT SWITCHES FOR QUERY 2:查看上下文切换是否频繁(过高说明并发争用严重)
注意:MEMORY 参数在 MySQL 5.7 中基本无效;SOURCE 虽能显示源码位置,但对线上调优帮助极小,别花时间解读。
真正容易被忽略的点是:profile 数据只存在于当前会话,且无法跨连接导出。如果需要长期归档或对比,得手动把 information_schema.PROFILING 表里的结果 SELECT 出来保存,否则 session 一断,全没了。










