绝大多数情况必须选#temp,因其会话级隔离可避免并发数据污染;##temp全局可见易致交叉读写;需显式drop、慎用select into、注意null处理及跨库语法差异。

SQL Server 该用 #temp 还是 ##temp?
绝大多数情况必须选 #temp,否则高并发下数据会互相污染。本地临时表 #temp 只在当前会话可见,SQL Server 在会话断开时自动清理;而全局临时表 ##temp 对所有会话可见,A 用户刚写入的数据,B 用户可能立刻读到或覆盖——这在报表调度、API 并发调用中极易引发脏读或主键冲突。
显式加 DROP TABLE IF EXISTS #tmp_result 是安全底线,不能依赖“自动清理”,尤其当存储过程异常退出后,虽最终会被释放,但若重试执行会直接报错 There is already an object named '#tmp_result' in the database。
常见错误现象:SELECT INTO ##tmp_shared FROM ... 看似省事,但多用户同时跑这个存储过程,##tmp_shared 的内容就是竞态结果,查出来的可能是别人上一轮的中间值。
MySQL 里为什么 CREATE TEMPORARY TABLE 不生效?
因为漏写了 TEMPORARY 关键字。MySQL 不识别 # 前缀,写成 CREATE TABLE tmp_calc 就真建成了永久表,下次执行直接报错 Table 'tmp_calc' already exists。
必须严格使用 CREATE TEMPORARY TABLE tmp_calc,且每次调用前加 DROP TEMPORARY TABLE IF EXISTS tmp_calc。注意:它不支持 SELECT INTO,只能先 CREATE 再 INSERT SELECT。
性能隐患点:如果字段含 TEXT 或 BLOB,MySQL 会强制把内存中的 MEMORY 引擎降级为磁盘 MyISAM,导致临时表操作变慢;此时应提前预估字段类型,避免隐式退化。
PostgreSQL 怎么让临时表不“赖着不走”?
只写 CREATE TEMP TABLE t1 是不够的,它会一直活到会话结束——而一个 Web 应用长连接可能复用同一会话多次调用存储过程,第二次执行就会卡在 relation "t1" already exists。
必须显式加上 ON COMMIT DROP,即 CREATE TEMP TABLE t1 ON COMMIT DROP。这样事务一提交,表就自动清空,下一次调用时可安全重建。
别在上面执行 TRUNCATE,它无效;也别指望靠事务回滚来“恢复”临时表数据——ON COMMIT DROP 已接管生命周期,回滚只影响数据,不影响表结构存在性。
大数据量时,#temp 和 @table 到底怎么选?
看行数:超过 1000 行,必须用 #temp;低于 100 行,优先用 @table。中间量(100–1000)视场景而定,但倾向 #temp,因优化器对它的统计信息更可靠。
@table 在函数里是唯一合法选择,但它是“哑”的:没统计信息、不能建索引(除主键外)、无法 UPDATE STATISTICS;所以函数内做多层 JOIN 或 WHERE 过滤时,执行计划容易误判为小表嵌套循环,实际扫全表。
#temp 支持 CREATE CLUSTERED INDEX,对后续 JOIN 性能提升明显;首次大批量插入后,手动跑一句 UPDATE STATISTICS #tmp_result 能让优化器立刻“看清”数据分布,避免计划固化在旧估算上。
WHERE status = 'Active' 或 JOIN 都可能意外过滤掉整行,且不报错。建议在 INSERT 后加 SELECT COUNT(*), COUNT(status) FROM #tmp_result 快速验空。











