【问题标题】:What is the best way to refresh a rollup table under load?在负载下刷新汇总表的最佳方法是什么?
【发布时间】:2009-01-31 03:12:30
【问题描述】:

我在我的 SQL Server 2005 数据库中创建了一个表,并用汇总值和计算值填充它。目的是避免在每次调用数据库时进行大量连接和分组。我希望此表每小时刷新一次,但我不确定在网站负载时执行此操作的最佳方法。如果我在一个事务中删除每条记录并重新填充表,那会成功还是会出现死锁和其他潜在问题?

【问题讨论】:

    标签: sql-server sql-server-2005 performance transactions deadlock


    【解决方案1】:

    我在几个项目中这样做的方式是在不同的模式中使用表的两个副本。所以像:

    CREATE SCHEMA fake WITH AUTHORIZATION dbo;
    CREATE SCHEMA standby WITH AUTHORIZATION dbo;
    GO
    
    CREATE TABLE dbo.mySummary(<...columns...>);
    
    CREATE TABLE fake.mySummary(<...columns...>);
    GO
    

    现在创建一个存储过程,截断并重新填充假表,然后在事务中在模式之间移动对象。

    CREATE PROCEDURE dbo.SwapInSummary
    AS
    BEGIN
        SET NOCOUNT ON;
    
        TRUNCATE TABLE fake.mySummary;
    
        INSERT fake.mySummary(<...columns...>)
            SELECT <expensive query>;
    
        BEGIN TRANSACTION;
            ALTER SCHEMA standby TRANSFER dbo.mySummary;
            ALTER SCHEMA dbo     TRANSFER fake.mySummary;
            ALTER SCHEMA fake    TRANSFER standby.mySummary;
        COMMIT TRANSACTION;
    END
    GO
    

    这可能是您可以让用户等待新数据刷新并且不会在读取过程中中断他们的最短时间。 (与 NOLOCK 相关的许多问题使其成为不太理想的替代方案,尽管不可否认,它很容易编码。)为了简洁/清晰,我省略了错误处理等,我还应该指出,如果你使用用于同步数据库的脚本,确保在两个表上命名约束、索引等相同,否则一半时间会不同步。在过程结束时,您可以截断新的 fake.MySummary 表,但如果您有空间,我喜欢将数据留在那里,以便随时与之前的版本进行比较。

    在 SQL Server 2005 之前,我在事务中使用 sp_rename 来完成完全相同的事情,但是由于我在工作中这样做,我很高兴切换到模式,因为当我这样做时,来自不可抑制的警告sp_rename 停止填充我的 SQL Server 代理历史日志。

    【讨论】:

    • 需要注意的是,当安全对象移动到新架构时,与安全对象关联的所有权限都将被删除。
    • @JustinStolle 是的,这是真的。我通常通过授予两个模式而不是单个对象的权限来解决这个问题。
    【解决方案2】:

    您还可以根据负载的重量创建索引视图,这可能是一个不错的选择

    【讨论】:

      【解决方案3】:

      这取决于您的数据库中的关系以及您针对它运行的查询。

      如果它是一个可以容忍陈旧数据的汇总表,您可以使用 NOLOCK 连接提示执行不带锁的 SELECT 的查询来填充它。 注意:只有在您确定后果时才能使用 NOLOCK 提示。

      通常可以重新调整索引以减少负载。

      【讨论】:

      • 谢谢。但是,我担心汇总表而不是规范化表。汇总表正在处理 Web 请求,而我想删除它的所有行并重新加载它。
      • @jedatu:你能更新汇总值而不是删除它们吗?
      • @Mitch-Wheat:我可以,但我也可能需要删除记录,这需要一个或多个大型“NOT IN”查询
      【解决方案4】:

      我决定在@temp 表变量中建立数据。然后我会将汇总 ID 复制到它们匹配的临时表中。最后,我将基于@temp表在汇总表中添加、更新和删除行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多