普通表还是全局临时表?

3

我和另外一个开发者正在讨论我们的任务需要使用哪种类型的表。基本上它将成为一个缓存,我们将在一天结束时截断它。就我个人而言,我认为对于这个任务没有使用全局临时表的必要性,因此只用普通表就可以了。

有没有哪种方式更有优势呢?

2个回答

5
如果这只是可以在服务重新启动时丢失的短暂数据,则在tempdb中使用普通表,或者如果数据不那么短暂,则在用户数据库中使用。从日志要求的角度来看,tempdb稍微更有效率一些。
全局临时表会在创建表的连接关闭后被删除。编辑:根据@cyberkiwi的编辑,BOL definitely explicitly say

全局临时表在创建后对任何用户和任何连接都可见,并在所有引用该表的用户从SQL Server实例断开连接时被删除。

尽管如此,在我的测试中,我无法获得这种行为。

连接1

CREATE TABLE ##T (i int)
INSERT INTO ##T values (1)
SET CONTEXT_INFO 0x01

连接 2

INSERT INTO ##T VALUES(4)
WAITFOR DELAY '00:01'
INSERT INTO ##T VALUES(5)

连接 3

SELECT OBJECT_ID('tempdb..##T') 
declare @killspid varchar(10) = (select 'kill ' +  cast(spid as varchar(5)) from sysprocesses where context_info=0x01)
exec (@killspid)
SELECT OBJECT_ID('tempdb..##T') /*NULL - But 2 is still 
                                 running let alone disconnected!*/

你能澄清一下tempdb如何更高效吗? - Jeremy Cantrell
1
@Jeremy - 首先,它将采用“简单”恢复模型,而您的其他数据库可能不会。但即使没有这个,它也需要比使用简单恢复模型的用户数据库记录更少的日志,因为它不必记录允许在服务器崩溃时重做事务的内容。 (tempdb在服务器重新启动时只需重新创建,因此不需要任何能力来回滚已提交并因此记录在事务日志中但尚未写入磁盘上的数据文件的事务) - Martin Smith

2

全局临时表

  • -ve: 只要创建全局临时表的连接失效,表也将一同消失。这对使用连接池的用户来说是有害的,因为连接池可以不断地交换连接并可能重置连接。
  • -ve: 需要不断检查表是否已经存在(重新启动后),如果不存在则需要创建它。
  • +ve: 在tempdb中进行简单的日志记录可以减少I/O和CPU活动。

普通表

  • +ve: 正常的日志记录可以将缓存与主数据库保持一致。如果您的“缓存”仍然非常关键,则会使其与数据库一起保持一致。
  • -ve: 见上文 更多的日志记录。
  • +ve: 表始终存在,并且对于所有连接都有效。

如果缓存是业务/关键数据的快速查找摘要之类的东西,即使在一天的尾声被重置/截断,我仍然更喜欢将其保留为db中的普通表。


我在测试##临时表的生命周期时得到了与您类似的结果。不确定BOL确切的含义是什么。这个答案让我想到,如果它们通过存储过程引用,可能会有所不同,但我还没有测试过(有其他事情要做!) - Martin Smith

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