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

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

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

最佳答案

我在一些项目中执行此操作的方法是在不同模式中使用表的两个副本。所以类似:

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 代理历史记录日志。

关于sql-server - 在负载下刷新汇总表的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/498142/

相关文章:

c# - 在 asp.net 中分块 FileUpload

sql-server - 具有持续集成的 SQL Server 数据库管理

c# - 将计算列用于 ID 时出现存储过程错误

sql - 子选择失败,但作为 View 它可以工作

asp.net - Web.config 身份验证错误

python - 如何限制 Python 进程的 I/O 消耗(可能使用 ionice)?

sql - SQL Server 2012 中的 LAST_VALUE 返回奇怪的结果

sql-server-2005 - SQL 左连接(条件之间)

PHP - 回显还是不回显?

C# 静态类成员和 System.Windows.Controls.Image 性能问题