tmp_table_size 和 max_heap_table_size 必须同步修改,实际生效值为二者较小者;低配机建议设为16m或32m,并写入my.ini后以管理员身份重启mysql服务。

tmp_table_size 和 max_heap_table_size 必须同步改
XAMPP 里 MySQL 的临时表内存限制由 tmp_table_size 和 max_heap_table_size 共同决定,实际生效值取二者中较小的那个。只调一个等于白调——比如你设了 tmp_table_size = 64M 却没动 max_heap_table_size(默认仍是 16M),那临时表最多还是只能用 16MB 内存。
低配电脑(如 2GB 内存)上,XAMPP 默认值往往偏高,容易导致查询频繁落盘。常见表现是慢查日志里反复出现 Using temporary; Using filesort,同时 SHOW STATUS LIKE 'Created_tmp%' 显示 Created_tmp_disk_tables 占比超过 20%。
- 先确认当前值:
SELECT @@tmp_table_size, @@max_heap_table_size; - 建议起手值:对 2GB 内存机器,设为
16M或32M;高于 4GB 可试64M - 动态设置(仅对新连接生效):
SET GLOBAL tmp_table_size = 33554432;和SET GLOBAL max_heap_table_size = 33554432;(32MB = 33554432 字节)
改完必须写进 my.ini 并管理员重启
XAMPP 在 Windows 下用的是 my.ini(不是 my.cnf),路径通常是 XAMPP\mysql\bin\my.ini。在线 SET GLOBAL 不持久,MySQL 重启就还原。
在 [mysqld] 段落下添加两行,注意单位可直接写 M:
tmp_table_size = 32M max_heap_table_size = 32M
改完必须以管理员身份重启 MySQL 服务——用 XAMPP 控制面板点“Stop”再“Start”,或命令行执行:net stop mysql → net start mysql。普通用户权限重启会失败,配置不加载。
为什么调了还是走磁盘临时表
参数生效 ≠ 查询就进内存。以下情况哪怕 tmp_table_size 设到 256M,MySQL 仍会强制写磁盘临时表:
- 查询字段含
TEXT、BLOB或JSON类型 → MEMORY 引擎不支持,直接跳过内存阶段 -
GROUP BY或ORDER BY的列没索引,且结果集宽(字段多/值长)→ 内存估算超限 - 用了
UNION、DISTINCT、子查询物化等操作 → MySQL 内部临时表生成逻辑更激进 - 连接已建立,
SET GLOBAL对旧连接无效 → 需重连或单独SET SESSION
验证是否真生效,不能只看 SHOW VARIABLES,得结合 SHOW STATUS LIKE 'Created_tmp%' 看后续查询行为变化。
别漏掉 innodb_buffer_pool_size 这个内存大户
XAMPP 默认把 innodb_buffer_pool_size 设成 128M 甚至更高,它和临时表参数抢同一块物理内存。低配机上这玩意常驻不释放,剩不下多少给临时表用。
实操建议:
- 在同一个
my.ini的[mysqld]段,加一行:innodb_buffer_pool_size = 32M - 如果几乎不用 InnoDB(比如纯 MyISAM 表),可压到
16M,但低于12M可能启动失败 - 禁用冗余引擎省初始化开销:
skip-archive、skip-blackhole、skip-federated
真正卡住性能的,往往是整体内存吃紧后系统主动回收临时表内存,而不是单个参数不够大。











