“Converting HEAP to ondisk”表示MySQL内部临时表因超出内存限制(tmp_table_size与max_heap_table_size的较小值)而溢出到磁盘,是性能瓶颈信号;需通过SET profiling=1、SHOW PROFILE block io, cpu确认其耗时占比是否超30%。

Converting HEAP to ondisk 是什么状态
这是 MySQL 线程在执行查询时,内部临时表从 MEMORY 引擎(即内存表)溢出到磁盘的明确信号。5.7+ 版本中不再显示 Converting HEAP to MyISAM,而是统一为 converting HEAP to ondisk —— 本质相同,只是底层实现改用 InnoDB 或 MyISAM 临时磁盘表,取决于 internal_tmp_disk_storage_engine 设置。
怎么确认是不是它拖慢了查询
不能只看 SHOW PROCESSLIST 里一闪而过的状态。要抓取完整生命周期:
- 先开 profiling:
SET profiling = 1; - 执行目标 SQL,比如:
SELECT * FROM orders GROUP BY user_id ORDER BY COUNT(*) DESC; - 查 ID:
SHOW PROFILES;找到对应 Query_ID - 重点看磁盘开销:
SHOW PROFILE block io, cpu FOR QUERY 3;
如果输出中 converting HEAP to ondisk 行的 Duration 占比超过 30%,或 Block_ops_out 显著高于其他阶段,基本可判定是瓶颈。
为什么 MEMORY 表会落到磁盘
不是内存不够就落盘,而是触发了两个硬性阈值中的任意一个:
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
-
tmp_table_size:单个内部临时表允许的最大内存大小(默认 16MB) -
max_heap_table_size:MEMORY 表引擎单表上限(默认也是 16MB)
二者取小值生效。只要估算结果集大小 > min(tmp_table_size, max_heap_table_size),MySQL 就强制落盘。注意:这个“估算”基于字段长度、行数预估,不一定准,尤其 VARCHAR、TEXT 类型容易误判。
临时表落盘的典型诱因和应对方向
常见触发场景不是“数据量大”,而是“结构设计让 MySQL 不得不建大临时表”:
-
GROUP BY/ORDER BY字段没索引,且结果集宽(比如SELECT a,b,c,d,e,...+GROUP BY a)→ 临时表存全字段 - 使用了
DISTINCT+ 多列,或UNION→ 需去重,内存撑不住 -
JOIN后再GROUP BY,驱动表太大 → 中间结果膨胀 - 排序字段含
TEXT/BLOB,或max_length_for_sort_data过小 → 排序缓冲不足,退化成多次磁盘读写
调大 tmp_table_size 和 max_heap_table_size 只是掩耳盗铃;真正该做的是缩小临时表体积——删掉 SELECT * 里的冗余字段,给 GROUP BY / ORDER BY 列加覆盖索引,或拆分复杂查询。










