咱们来梳理一下 SQL Server 里 临时表(#TempTable表变量(@TableVariable 的主要区别:

1. 存储位置

  • #TempTable 临时表
    存储在 tempdb 数据库里,可以有索引、统计信息,支持事务
  • @TableVariable 表变量
    本质上也是存储在 tempdb,但 SQL Server 会把它当作变量来管理,通常不会维护统计信息。

2. 生命周期和作用域

  • #TempTable
    在当前会话(Session)和作用域中有效。比如你在存储过程中建了 #TempTable存储过程结束后临时表就会被自动销毁。
  • @TableVariable
    生命周期和普通变量类似,只在声明它的 批处理(batch)或存储过程 中有效,出了作用域就没了。

3. 索引与约束

  • #TempTable
    可以显式创建 索引(Clustered/Nonclustered)、约束(Primary Key, Unique, Default, Check)等。
  • @TableVariable
    只能通过 主键或唯一约束 来间接生成索引,不能直接建非聚集索引,功能有限。

4. 事务行为

  • #TempTable
    参与事务,支持 回滚(ROLLBACK)
  • @TableVariable
    不真正参与事务,ROLLBACK 不会影响它(数据仍然保留)。

5. 性能差异

  • 小数据量@TableVariable 开销更小,适合保存少量数据、临时计算结果。
  • 大数据量#TempTable 更合适,因为它有统计信息,优化器能生成更优执行计划。
  • 优化器差异
    • #TempTable 有统计信息 → 可以生成基于数据量的执行计划。
    • @TableVariable 默认假设只有 1 行 → 当实际数据很多时,容易导致性能问题。

6. 示例代码

-- 临时表
CREATE TABLE #TempTable (
    ID INT PRIMARY KEY,
    Name NVARCHAR(50)
);

INSERT INTO #TempTable VALUES (1, 'Alice'), (2, 'Bob');

SELECT * FROM #TempTable;

DROP TABLE #TempTable;  -- 手动删除

-- 表变量
DECLARE @TableVariable TABLE (
    ID INT PRIMARY KEY,
    Name NVARCHAR(50)
);

INSERT INTO @TableVariable VALUES (1, 'Alice'), (2, 'Bob');

SELECT * FROM @TableVariable;
-- 无需 DROP,出了作用域自动释放

总结

  • 少量数据、简单逻辑 → 用 @TableVariable(轻量、方便)。
  • 大数据量、复杂查询、需要索引优化 → 用 #TempTable(性能更好)。