【问题标题】:Normal table or global temp table?普通表还是全局临时表?
【发布时间】:2011-06-12 12:47:09
【问题描述】:

我和另一位开发人员正在讨论哪种类型的表格更适合我们的任务。它基本上是一个缓存,我们将在一天结束时截断它。就个人而言,我认为没有任何理由为此使用普通表以外的任何东西,但他想使用全局临时表。

两者之间有什么优势吗?

【问题讨论】:

    标签: sql-server temp-tables


    【解决方案1】:

    使用tempdb 中的普通表,如果这只是临时数据,您可以承受在服务重启时丢失,或者如果数据不是临时数据,则使用用户数据库。

    tempdb 在日志记录要求方面效率略高。

    一旦所有引用连接创建表的连接关闭,全局临时表就会被删除。

    编辑:遵循@cyberkiwi 的编辑。 BOL 做definitely explicitly say

    全局临时表对 任何用户和他们之后的任何连接 已创建,并在全部删除时删除 引用表的用户 断开与 SQL 实例的连接 服务器。

    在我的测试中,我也无法获得这种行为。

    连接 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 - 它将在simple 恢复模式中开始,而您的其他数据库可能不会。但是即使没有它,它也需要比在具有简单恢复模型的用户数据库中发生的日志记录更少,因为它不必记录允许它在服务器崩溃的情况下重做事务的内容。 (tempdb 只是在服务器重新启动时重新创建,因此不需要任何能力来前滚已提交并因此记录在事务日志中但尚未写入磁盘上的数据文件的事务)
    【解决方案2】:

    全局临时表

    • -ve:一旦连接that created 表超出范围,它需要 与它的表。如果您使用可以不断交换连接并可能重置连接的连接池,则会造成破坏
    • -ve:你需要不断检查表是否已经存在(重启后),如果不存在则创建它
    • +ve:tempdb 中的简单日志记录可减少 I/O 和 CPU 活动

    普通表

    • +ve: 正常日志将缓存与主数据库保持一致。如果您的“缓存”得到维护但仍然是关键任务,这将使其与数据库保持一致
    • -ve:从上方跟随更多日志记录
    • +ve:表始终存在,适用于所有连接

    如果缓存类似于业务/关键数据的快速查找摘要,即使它在一天结束时被重置/截断,我更愿意将其保留在数据库中的正常表中。

    【讨论】:

    • 我在测试##temp 表的生命周期时得到了与您类似的结果。不确定 BOL 的确切含义。 This answer 让我觉得如果通过存储过程引用它们可能会有所不同,但我还没有测试过(还有其他事情要做!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 2023-03-27
    • 1970-01-01
    • 2023-04-08
    • 2011-12-17
    • 1970-01-01
    • 2015-12-11
    相关资源
    最近更新 更多