临时表是什么
临时表是会话级的表:只在创建它的会话里可见,会话结束自动清理。它适合拆分复杂批处理、暂存中间结果、把长语句拆成多步。使用时要注意连接池复用(连接归还后临时表可能还在)与事务语义差异。
基本信息
| MySQL 生命周期 | 会话结束自动清理 |
|---|---|
| PostgreSQL 生命周期 | 支持 ON COMMIT DROP 在事务提交时清理 |
| 可见性 | 仅创建会话可见,不同会话的同名临时表互不干扰 |
| 写入成本 | 临时表同样产生 IO,不是免费的中间层 |
| 连接池风险 | 连接复用时长生命周期临时表可能残留 |
典型使用场景
- 把复杂批处理拆成多步暂存中间结果
- 给报表预处理数据
- 批量任务里做去重与分片
- 测试时构造隔离的数据集
- 替代过长的嵌套子查询
MySQL 写法
MySQL 写法
CREATE TEMPORARY TABLE tmp_top_users (
user_id BIGINT PRIMARY KEY,
total DECIMAL(12,2)
) ENGINE = InnoDB;
INSERT INTO tmp_top_users
SELECT user_id, SUM(total) FROM orders GROUP BY user_id;
SELECT * FROM tmp_top_users ORDER BY total DESC LIMIT 10;
DROP TEMPORARY TABLE IF EXISTS tmp_top_users; -- 用完显式删除PostgreSQL 写法
PostgreSQL 写法
-- ON COMMIT DROP:事务提交即清理,适合短生命周期场景
CREATE TEMP TABLE tmp_top_users (
user_id bigint PRIMARY KEY,
total numeric(12,2)
) ON COMMIT DROP;
INSERT INTO tmp_top_users
SELECT user_id, SUM(total) FROM orders GROUP BY user_id;
SELECT * FROM tmp_top_users ORDER BY total DESC LIMIT 10;两库对照
| 维度 | MySQL | PostgreSQL |
|---|---|---|
| 生命周期 | 会话结束清理 | 可选提交时清理 |
| 可见性 | 仅本会话 | 仅本会话 |
| 同名冲突 | 不同会话互不影响 | 同 |
| 显式清理 | DROP TEMPORARY TABLE | DROP TABLE |
| 事务语义 | 建表语句不参与回滚 | 建表支持事务语义,可回滚 |
连接池里要小心:连接归还后临时表可能依然存在,后续复用该连接的业务会读到旧数据或撞名,用完显式删除更安全。
临时表不是零成本:写入同样落盘或占用内存,大中间结果会带来明显 IO,先评估规模再决定用它还是直接改写查询。
临时表与普通表同名时按临时表优先:这正是连接池残留问题的根源,排查「查到的数据不对」时先确认当前会话里有没有同名临时表。
临时表的统计信息通常不完整,基于它做复杂连接时优化器可能选错计划;关键批处理完成后建议落成普通表再分析。