代码之家  ›  专栏  ›  技术社区  ›  jedatu

在负载下刷新汇总表的最佳方法是什么?

  •  2
  • jedatu  · 技术社区  · 17 年前

    我在SQLServer2005数据库中创建了一个表,并用摘要和计算值填充了它。目的是避免每次调用数据库时都进行大量的连接和分组。我希望这张表每小时刷新一次,但我不确定在网站负载下这样做的最佳方式。如果我删除每条记录并在一个事务中重新填充表,这会奏效吗?还是会出现死锁和其他问题?

    4 回复  |  直到 17 年前
        1
  •  5
  •   Aaron Bertrand    14 年前

    我在一些项目中这样做的方式是在不同的模式中使用表的两个副本。所以类似于:

    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相关的许多问题使其成为不太理想的替代方案,尽管不可否认,它很容易编码。)为了简洁明了,我省略了错误处理等,我还应该指出,如果你使用脚本来同步数据库,请确保在两个表上命名约束、索引等相同,否则你会有一半的时间不同步。在程序结束时,您可以对新的假货进行TRUNCATE。MySummary表,但如果你有空间,我喜欢把数据留在那里,这样我就可以随时与以前的版本进行比较。

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

        2
  •  1
  •   SQLMenace    17 年前

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

        3
  •  0
  •   Mitch Wheat    17 年前

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

    如果它是一个可以容忍过时数据的汇总表,您可以使用查询来填充它,这些查询使用NOLOCK连接提示在没有锁的情况下执行SELECT。 笔记

    通常有重新调整索引的空间,以减少负载。

        4
  •  0
  •   jedatu    17 年前