Navicat的Profile页签无法显示Copying to tmp table阶段,因其仅封装已弃用的SHOW PROFILE,需结合SHOW PROCESSLIST与SHOW PROFILE IO交叉验证,并通过EXPLAIN FORMAT=JSON确认索引缺失导致临时表膨胀。

Navicat的Profile页签根本看不到Copying to tmp table阶段
Navicat的Profile页签只显示sending data、creating sort index这类通用阶段名,不会出现Copying to tmp table或Copying to tmp table on disk——这是MySQL原生命令SHOW PROCESSLIST里才有的真实状态。Profile页签只是对SHOW PROFILE的图形封装,而SHOW PROFILE本身在MySQL 8.0+中已被弃用,且不暴露临时表落盘细节。
必须用SHOW PROCESSLIST + SHOW PROFILE IO组合定位
真正卡在临时表环节的查询,需要两步交叉验证:
- 先在Navicat查询窗口执行
SHOW PROCESSLIST,找到State列为Copying to tmp table或Copying to tmp table on disk的线程ID(即Id列值) - 立即在同一连接中执行
SHOW PROFILE IO FOR QUERY N(N填上一步查到的ID),重点看IO read bytes和IO write bytes是否异常高——若后者远大于前者,说明正在往磁盘写临时表 - 再补一句
EXPLAIN FORMAT=JSON,检查输出里used_columns和rows_examined是否远超预期,确认是不是因缺失索引导致中间结果集过大
为什么不能只靠调大tmp_table_size
盲目执行SET GLOBAL tmp_table_size = 268435456(256MB)解决不了本质问题:
-
max_heap_table_size和tmp_table_size取较小值生效,改一个没用 - 调大后可能把内存耗尽触发OOM,尤其在多并发场景下
- 即使临时表留在内存,
Using temporary仍表示执行计划低效——排序/分组逻辑本该由索引完成,却被迫交由服务器层处理 - EXPLAIN中同时出现
Using temporary和Using filesort是强信号,说明ORDER BY或GROUP BY字段完全没走索引
最简验证路径:三行命令定乾坤
在Navicat中新开一个查询窗口,按顺序执行(必须同一连接):
SELECT * FROM orders JOIN users ON orders.user_id = users.id WHERE users.status = 1 ORDER BY orders.created_at DESC LIMIT 20;-
SHOW PROCESSLIST;→ 找到对应Id -
SHOW PROFILE IO FOR QUERY 1;(假设ID是1)→ 若Copying to tmp table阶段IO write bytes> 10MB,基本可断定是磁盘临时表瓶颈
这时候别急着改参数,先看EXPLAIN输出里的key是否为NULL、type是否为ALL——临时表只是表象,索引缺失才是根因。


















