MySQL 8.0.16起默认临时表引擎为TempTable而非Memory,由internal_tmp_mem_storage_engine参数控制;TempTable支持BLOB/TEXT、按页落盘、内存池可控,而Memory受限多且不自动落盘。

MySQL 8.0 临时表默认用的是 TempTable,不是 Memory
MySQL 8.0.16 起,internal_tmp_mem_storage_engine 默认值从 MEMORY 改为 TEMPTABLE。这意味着大多数隐式临时表(如 GROUP BY、DISTINCT、UNION、窗口函数中间结果)默认走的是 TEMPTABLE 引擎,而非老版本的 MEMORY。这个变化直接影响内存使用、磁盘回退行为和排序性能。
判断当前设置:SELECT @@internal_tmp_mem_storage_engine;
常见误判:看到 tmp_table_size 和 max_heap_table_size 就以为还在控制 MEMORY 行为 —— 实际上这两个参数对 TEMPTABLE 的内存部分**仅间接生效**(用于限制其内存池大小),真正决定是否落盘的是 temptable_max_ram。
Memory 引擎临时表的典型问题与适用场景
MEMORY 引擎临时表在 MySQL 8.0 中仍存在,但只在显式创建(CREATE TEMPORARY TABLE ... ENGINE=MEMORY)或某些特定优化路径下触发。它的问题很实在:
- 不支持
TEXT/BLOB类型,遇到这类字段会直接报错ERROR 1163 (42000): The used table type doesn't support BLOB/TEXT columns - 所有行数据必须能放进单个内存页(受
max_heap_table_size限制),超限就报ERROR 1114 (HY000): The table is full,不会自动转磁盘 - 不支持行级压缩或变长字段高效存储,固定长度模拟导致内存浪费严重(比如
VARCHAR(255)存 "a" 也占 255 字节) - 无并发写入优化,高并发临时表操作易成锁瓶颈
它唯一优势是确定性快 —— 如果你能严格控制字段类型、长度和总行数,且不涉及大字段,MEMORY 在小规模、结构简单、纯内存场景下仍有可预测的低延迟。
TempTable 引擎的关键配置与调优点
TEMPTABLE 是 MySQL 8.0 自研的内存+磁盘混合引擎,目标就是解决 MEMORY 的硬伤。它的行为由几个关键参数联动控制:
-
temptable_max_ram:内存池上限(默认 1GB)。超过此值,新分配的内存页会直接写入磁盘临时文件(/tmp或tmpdir指定路径),不是整张表落盘,而是按需分页落盘 -
tmp_table_size和max_heap_table_size:对TEMPTABLE**不直接限制建表大小**,但影响其内部内存分配策略;当两者中较小值 ≤temptable_max_ram时,TEMPTABLE才可能全程内存操作 -
temptable_use_mmap:启用(ON,默认)则用 mmap 分配大块内存,减少 malloc 开销;但容器环境或内存受限机器建议关掉(OFF),避免 mmap 占用虚拟地址空间引发 OOM - 磁盘临时文件位置由
tmpdir控制,务必确保该路径所在磁盘有足够空间且 I/O 吞吐够用(SSD > HDD)
示例调整(my.cnf):
temptable_max_ram = 2G<br>tmpdir = /ssd/tmp<br>temptable_use_mmap = OFF
怎么判断临时表到底用了哪种引擎、有没有落盘
不能只看执行计划里的 “Using temporary” —— 这只是表示用了临时表,不说明引擎或介质。真实情况得查运行时状态:
- 开启 performance_schema:
UPDATE performance_schema.setup_instruments SET ENABLED='YES' WHERE NAME LIKE 'stage/innodb/alter%';(实际需启用相关 stage instruments) - 查
performance_schema.events_stages_current或历史表,找阶段名含creating sort index或writing to tmp table的记录,结合WORK_COMPLETED和WORK_ESTIMATED看是否远超内存容量 - 最直接方式:监控
SHOW GLOBAL STATUS LIKE 'Created_tmp%';,重点看:
–Created_tmp_tables:总临时表创建数
–Created_tmp_disk_tables:其中落盘的数量
若后者占比持续 > 5%,说明temptable_max_ram或磁盘 I/O 已成瓶颈 - 临时文件本身在
tmpdir下以#sql_<pid>_<thread_id>_<seq>.MYD</seq></thread_id></pid>或ibtmp1(InnoDB 共享临时表空间)形式存在,可 ls -l 观察增长
复杂点在于:同一个查询可能混合使用两种引擎 —— 比如子查询走 TEMPTABLE,外层 JOIN 又触发一个显式 MEMORY 临时表。调试时得结合 EXPLAIN FORMAT=TREE 和 status 计数交叉验证。


















