MySQL没有全局临时表,CREATE TEMPORARY TABLE仅限当前会话;需共享中间结果时应使用命名规范的普通表或ENGINE=MEMORY表;性能问题多因临时表未生效或落盘,须通过EXPLAIN和SHOW STATUS诊断,并确保tmp_table_size与max_heap_table_size设为相同值。

MySQL 临时表根本不是“全局”的
MySQL 没有真正意义上的「全局临时表」——CREATE TEMPORARY TABLE 创建的表只对当前会话可见,断开连接即自动销毁。所谓“全局临时表”是常见误解,实际需求往往是:多个会话需要共享中间结果、避免重复计算,又不想污染正式库。这时候该用普通表+命名规范(如 tmp_user_agg_202405)或内存表(ENGINE=MEMORY),而不是强求不存在的“全局临时表”。
临时表性能差?先确认它真被用了
很多性能问题其实源于临时表压根没生效,或者被强制落盘。执行 EXPLAIN 查看 Extra 字段:
- 出现
Using temporary:说明优化器决定用内部临时表(可能在内存,也可能落磁盘) - 但不等于你显式建的
TEMPORARY TABLE被用了 - 如果
Sort_merge_passes或Created_tmp_disk_tables值飙升,才是临时表性能瓶颈信号
查法:SHOW GLOBAL STATUS LIKE 'Created_tmp%';
显式临时表怎么写才快
如果你确实需要手动建临时表缓存中间结果(比如复杂 JOIN 后的聚合),注意这几点:
- 显式指定
ENGINE=MEMORY,避免默认 InnoDB 的事务开销和磁盘刷写 - 字段尽量精简:只保留后续查询真正需要的列,避免
SELECT * - 加必要索引——
MEMORY表支持HASH(等值查快)和BTREE(范围查快),按主查询条件选 - 别忘了
DROP TEMPORARY TABLE,虽然会话结束自动删,但长事务中不释放会影响tmp_table_size内存限额
示例:
CREATE TEMPORARY TABLE tmp_active_users ENGINE=MEMORY AS SELECT user_id, MAX(login_time) AS last_login FROM logs WHERE log_date >= '2024-05-01' GROUP BY user_id; ALTER TABLE tmp_active_users ADD INDEX idx_user (user_id) USING HASH;
tmp_table_size 和 max_heap_table_size 必须配平
这是最容易被忽略的性能开关。MySQL 用这两个参数共同控制内存临时表上限:
-
tmp_table_size是单个内部临时表(优化器自动建的)内存上限 -
max_heap_table_size是显式ENGINE=MEMORY表的上限 - 但 MySQL 实际取二者**较小值**作为最终阈值。如果只调大
tmp_table_size,而max_heap_table_size还卡在默认 16M,那MEMORY临时表照样会转磁盘
查当前值:SHOW VARIABLES LIKE '%table_size%';;设为一致(比如都设成 256M)再测试。











