SQL Server 临时表 vs 表变量

4
我们的客户数据库管理员要求我们在报表存储过程中不使用临时表(#Table),而是使用表变量。
表变量比临时表效率低吗?
另外,如果我创建一个名为#table的表,而不是##table,那么只有一个#的表是会话表,而##是全局表,对吗?当stored procedure完成并且您没有执行DROP TABLE #table ... #table是否仍然存在?如果它是基于会话的,那么我以后还能访问它吗?

2
注意:表变量没有统计信息,并且不参与事务。需要记住的事情。 - Mitch Wheat
很多人错误地认为表变量总是在内存中,而临时表会存储在 tempdb 中并击中磁盘。这两种观点都不完全正确(实际上它们都存储在 tempdb 中,如果可能的话,它们都会留在内存中,如果需要,它们都会溢出到磁盘)。 - Damien_The_Unbeliever
3个回答

2

表变量可以比临时表(参见 KB #243586 和 KB #305977)导致更少的存储过程重新编译,并且——由于它们无法回滚——不会影响事务日志。

##table 属于全局临时表。是的,#table不存在,因为它只存在于给定范围内,并且您从未在给定范围之外访问它。

编辑

我还想指出使用 CTE(公共表达式)也很不错,因为它也可以作为临时表。 查看此答案以获取详细信息:CTE 或临时表哪个更有效?


给定的问题“yes #table not exist because its in given scope only and you never access it out the given scope”是误导性的。#table存在于会话范围内。因此,您可以从同一会话中调用的另一个存储过程中再次访问它。这意味着它必须在表变量被清除之前挂起更长的时间。 - Martin Brown

0

我不是100%确定你在问什么,因为你的标题提到了表变量,要求使用表变量,但你的问题并没有涉及到表变量... 但是表变量的声明方式如下:

DECLARE @Banana TABLE 
(
  Id INT,
  Name VARCHAR(20)
)

-1

如果在存储过程中创建了本地临时表(#table),则在存储过程完成后将被删除。BOL说:

临时表在超出范围后会自动删除, 除非使用DROP TABLE显式删除:

  • 存储过程中创建的本地临时表在存储过程完成后会自动删除。该表可以由存储过程创建的任何嵌套存储过程引用。该表不能被创建表的进程引用。

  • 所有其他本地临时表都会在当前会话结束时自动删除。

  • 全局临时表会在创建表的会话结束并且所有其他任务停止引用它们时自动删除。任务和表之间的关联仅维持单个Transact-SQL语句的生命周期。这意味着,当创建会话结束时,最后一个活动引用该表的Transact-SQL语句完成后,全局临时表会被删除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接