我正在努力优化一些旧的tsql查询。
我发现有几个使用## table这是一个全局临时表。
SQL Server tables: what is the difference between @, # and ##?
我看到的是,在这些存储过程的顶部,它检查这个##表是否存在,如果存在,它会删除表,然后继续重新创建这个##表。这些是使用此##表的唯一存储过程。
我的问题是,为什么每次只重新创建时都会使用全局表(## table)?通过#table(本地表)上的##表获得了一些效率吗?
我想用#tables替换这些##表,因为它们不是真正的全局,但由于我对这些## table缺乏了解而不想引起效率问题或导致问题(S)。 (当同时运行查询同时尝试删除并重新创建表时,它也会导致一些分裂的第二个问题,而实际上如果它们是内部表#table,则此问题永远不会发生)
我第一次遇到## table。
答案 0 :(得分:3)
@,#和##之间的差异是:
@
仅在声明它的批处理中可见。实施例
DECLARE @t AS TABLE (c INT NOT NULL );
INSERT INTO @t VALUES(1) --correct
GO
INSERT INTO @t VALUES(2) --error. after GO it is another batch
#
在创建该临时本地表的会话中可见。实施例
CREATE TABLE #t (c INT NOT NULL );
INSERT INTO #t VALUES(1) --correct
GO
INSERT INTO #t VALUES(2) --correct
所有会话都可以看到 ##
,而创建临时全局表的会话不会终止。例:
打开两个SSMS
窗口。在一个创建表CREATE TABLE ##t (c INT NOT NULL );
中
从其他窗口尝试选择SELECT * FROM ##t --no error
关闭第一个窗口。再试一次SELECT * FROM ##t --error. session that created temp global table was terminated
所以答案是:如果你需要多个会话来使用相同的临时表,你应该使用##
,否则使用#
。如果只有一个批次,则使用@
。
@
个变量被销毁。
#
您可以手动删除表,或者在终止时创建它的级别时将其销毁。
##
您可以手动删除表,否则会在终止时创建会话时将其销毁。