这是《MySQL 8.0 源码与内核实战》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 MySQL 中“临时表”有三类:用户 TEMPORARY 表、SQL 层内部临时表和存储引擎内部临时结构。它们的生命周期、复制行为和内存策略不同。
26.1 用户临时表
CREATE TEMPORARY TABLE tmp_stat(
user_id BIGINT PRIMARY KEY,
amount DECIMAL(12,2)
) ENGINE=InnoDB;
特点:
- 会话可见;
- 同名临时表遮蔽普通表;
- 连接关闭自动清理;
- 不向传统复制流写入普通 DML;
- 某些 DDL 和复制场景有限制。
连接池长连接要显式 DROP TEMPORARY TABLE,避免残留。
26.2 内部临时表
触发场景:
- GROUP BY 无合适索引;
- DISTINCT;
- UNION;
- 派生表物化;
- 子查询物化;
- 窗口函数;
- ORDER BY 无法使用索引;
- JSON 或复杂表达式。
观测:
SHOW STATUS LIKE 'Created_tmp%';
EXPLAIN FORMAT=TREE SELECT ...;
26.3 TempTable 引擎
8.0 内部内存临时表默认使用 TempTable:
SHOW VARIABLES LIKE 'internal_tmp_mem_storage_engine';
SHOW VARIABLES LIKE 'temptable_max_ram';
SHOW VARIABLES LIKE 'temptable_max_mmap';
超过内存能力后会转磁盘 InnoDB 临时表,可能产生明显延迟。
26.4 磁盘临时表
临时表空间:
SHOW VARIABLES LIKE 'innodb_temp_data_file_path';
SELECT * FROM information_schema.innodb_session_status LIMIT 5;
大排序或大聚合会占用会话临时段,连接释放后空间可复用,文件不一定缩小。
26.5 降低临时表压力
- 为 GROUP BY / ORDER BY 建匹配索引;
- 减少返回行和列;
- 先过滤再聚合;
- 拆分复杂 SQL;
- 分页避免大 offset;
- 大报表走分析库;
- 控制排序缓冲和临时表阈值。
26.6 MEMORY 表
MEMORY 引擎表数据放内存,默认 HASH 索引,重启后数据清空。适合临时配置或小字典,不适合持久业务数据。
限制:
- 变长类型支持有限;
- 重启丢数据;
- 复制和恢复语义需谨慎;
- 不支持 InnoDB 事务能力。
本章小结
临时对象要区分用户临时表、内部内存临时表和磁盘临时表。查询大量落盘通常是排序、分组或物化导致,应从索引、过滤和查询结构优化。
思考题
- 用户临时表为什么在长连接中要显式清理?
- 哪些 SQL 会创建内部临时表?
- TempTable 超过内存后会发生什么?
- 如何通过索引减少排序落盘?
- MEMORY 表适合哪些场景?