max_heap_table_size与tmp_table_size共同决定内存临时表上限,取二者较小值;单独调整一个无效,且需同步保障innodb_buffer_pool_size充足并注意会话级内存叠加压力。

MySQL 的 max_heap_table_size 不是“支持大内存运算”的开关,它只控制单个内存表(ENGINE=MEMORY)或内部临时表在内存中能用的最大空间;超过就落盘,不等于提升整体查询内存上限。
为什么改了 max_heap_table_size 还报 “The table is full”?
常见于 CREATE TEMPORARY TABLE ... SELECT 或复杂 GROUP BY/ORDER BY 场景。错误不是因为没改这个参数,而是:
-
tmp_table_size和max_heap_table_size必须同时调高,且取两者中的较小值作为实际限制 - 会话级设置(
SET SESSION tmp_table_size = ...)只对当前连接生效,脚本或应用重连后失效 - 如果查询涉及 BLOB/TEXT 列,MySQL 会直接强制使用磁盘临时表,无视这两个参数
-
innodb_buffer_pool_size过小导致频繁刷脏页,间接加剧内存紧张,让临时表更易落盘
如何安全地调大内存表上限?
修改需兼顾全局与会话、内存表与临时表、InnoDB 缓冲池三者配比:
- 在
/etc/my.cnf的[mysqld]段下统一设为相同值:max_heap_table_size = 512M tmp_table_size = 512M
- 若仅需临时提升(如某次大数据量导出),用会话级命令:
SET SESSION tmp_table_size = 536870912;(单位字节) - 必须同步检查
innodb_buffer_pool_size是否足够——例如 32G 内存服务器,建议设为24G,否则调高临时表上限反而引发 swap - 重启 MySQL 后验证:
SHOW VARIABLES LIKE 'max_heap_table_size';和SHOW VARIABLES LIKE 'tmp_table_size';确保值一致且生效
max_heap_table_size 和 tmp_table_size 的关键区别
它们作用对象不同,但协同生效:
-
max_heap_table_size:只约束显式创建的ENGINE=MEMORY表,也影响用户自建内存表的MAX_ROWS计算 -
tmp_table_size:只约束 MySQL 内部自动创建的内存临时表(如排序、聚合中间结果),不控制用户建的 MEMORY 表 - 当两者不等时,MySQL 取较小值作为所有临时表的内存上限——所以单独调高一个没用
- 注意:该限制是“每个线程独立计算”,100 个并发连接可能最多占用 100 × 512M 内存,需预估总开销
真正卡住大查询的往往不是这两个参数本身,而是 sort_buffer_size、join_buffer_size 等会话级缓冲叠加后的总内存压力,以及 innodb_buffer_pool_size 是否留足余量。调参前先看 SHOW STATUS LIKE 'Created_tmp%';,确认是否真因临时表落盘导致性能下降。


















