如何更改此过程以在SQL Server 2005中逐日删除记录

如何更改此过程以在SQL Server 2005中逐日删除记录,sql,sql-server,Sql,Sql Server,嘿,大家好,我现在只是越来越懒了。但是,我知道你们都能帮助我,这是一件好事 我有一个每天晚上运行的表格清理和删除程序。它足够基本,支持删除数据库中任何超过3天的记录 该进程每晚都会失败,因为当我们一次删除超过1天的记录时,我会收到一个事务日志完整错误。更改事务日志设置将是一件痛苦的事情 SOO,有人能告诉我如何更新程序,让它删除3天前的所有内容,比如说7天。这意味着返回3天,然后在过去7天内一次删除每个表的数据 我们是一家全天候监控的能源商店,我可以肯定,如果它在7天内不运行,会有人注意到 AL

嘿,大家好,我现在只是越来越懒了。但是,我知道你们都能帮助我,这是一件好事

我有一个每天晚上运行的表格清理和删除程序。它足够基本,支持删除数据库中任何超过3天的记录

该进程每晚都会失败,因为当我们一次删除超过1天的记录时,我会收到一个事务日志完整错误。更改事务日志设置将是一件痛苦的事情

SOO,有人能告诉我如何更新程序,让它删除3天前的所有内容,比如说7天。这意味着返回3天,然后在过去7天内一次删除每个表的数据

我们是一家全天候监控的能源商店,我可以肯定,如果它在7天内不运行,会有人注意到

ALTER PROCEDURE [dbo].[PruneData]
    (
    @cutoffDate DateTime
    )
AS
BEGIN
    declare @threeDayCutoffDate DATETIME
    set @threeDayCutoffDate  = dateadd(hh, 5, DATEADD(dd, -3,dbo.DateOnly(getutcdate())))
    delete from LMP_DayAhead where interval < @threeDayCutoffDate
    delete from LMP_RealTime where interval < @threeDayCutoffDate
    delete from LMP_RealTimeIntegrated where interval < @threeDayCutoffDate
    delete from ZonalMCP where interval < @threeDayCutoffDate
    delete from SyncJob where synctime < @threeDayCutoffDate
    RETURN
END
ALTER过程[dbo].[PruneData]
(
@截止日期日期时间
)
作为
开始
声明@Threeday截止日期日期时间
set@threeDayCutoffDate=dateadd(hh,5,dateadd(dd,-3,dbo.DateOnly(getutcdate()))
从LMP_DayAhead中删除,其中间隔<@Threeday截止日期
从LMP_实时删除,其中间隔<@Threeday截止日期
从LMP_RealTimeIntegrated中删除,其中间隔<@Threeday截止日期
从ZonalMCP中删除,其中间隔<@Threeday截止日期
从SyncJob中删除,其中synctime<@ThreeDayCutoff日期
返回
结束

要降低日志压力,需要批量删除。大概是这样的:

ALTER PROCEDURE [dbo].[PruneData]
    (
    @cutoffDate DateTime
    )
AS
BEGIN
    declare @threeDayCutoffDate DATETIME
    declare @rows bigint;
    declare @batchsize int;
    set @threeDayCutoffDate  = dateadd(hh, 5, DATEADD(dd, -3,dbo.DateOnly(getutcdate())))
    set @batchsize = 1000;
    while (1=1)
    begin
        set @rows = 0;
        delete top (@batchsize) from LMP_DayAhead where interval < @threeDayCutoffDate;
        set @rows = @rows + @@ROWCOUNT;
        delete top (@batchsize) from LMP_RealTime where interval < @threeDayCutoffDate
        set @rows = @rows + @@ROWCOUNT;
        delete top (@batchsize) from LMP_RealTimeIntegrated where interval < @threeDayCutoffDate
        set @rows = @rows + @@ROWCOUNT;
        delete top (@batchsize) from ZonalMCP where interval < @threeDayCutoffDate
        set @rows = @rows + @@ROWCOUNT;
        delete top (@batchsize) from SyncJob where synctime < @threeDayCutoffDate
        set @rows = @rows + @@ROWCOUNT;

        if 0 = @rows
        begin
            break;
        end
    end
    RETURN
END
ALTER过程[dbo].[PruneData]
(
@截止日期日期时间
)
作为
开始
声明@Threeday截止日期日期时间
声明@rows-bigint;
声明@batchsize int;
set@threeDayCutoffDate=dateadd(hh,5,dateadd(dd,-3,dbo.DateOnly(getutcdate()))
设置@batchsize=1000;
而(1=1)
开始
设置@rows=0;
从LMP_DayAhead中删除top(@batchsize),其中间隔小于三天截止日期;
设置@rows=@rows+@@ROWCOUNT;
从LMP_RealTime中删除top(@batchsize),其中间隔<@Threeday截止日期
设置@rows=@rows+@@ROWCOUNT;
从LMP_RealTimeIntegrated中删除top(@batchsize),其中间隔小于三天截止日期
设置@rows=@rows+@@ROWCOUNT;
从ZonalMCP中删除top(@batchsize),其中间隔<@Threeday截止日期
设置@rows=@rows+@@ROWCOUNT;
从SyncJob中删除top(@batchsize),其中synctime<@ThreeDayCutoff日期
设置@rows=@rows+@@ROWCOUNT;
如果0=@行
开始
打破
结束
结束
返回
结束

有很多方法可以优化它,例如,一旦一个表被删减,在下一个循环迭代中跳过它。最终的优化是完全避免删除。相反,使用滚动窗口分区切换方案:按天对表进行分区,每天切换出最后一个分区并切换到新分区。这几乎是瞬间的。请参阅和

即使您将其分为多个批次,从开始到结束,您都需要在相同的时间范围内(秒/分钟)删除相同数量的记录。事务日志需要保留所有这些记录,直到您完成完整备份或日志备份

您需要做的是增加事务日志备份频率,并将日志备份放在删除运行的批之间。假设您预计每天大约有100万条记录被删除。尽管您说过要返回并删除7天(由3天抵消),但让我们将系统设计为一次处理3天。因此,如果您已经7天没有运行它(不应该发生,因为您声明它每天运行),则需要3天才能赶上(每天运行3次)

下一步是将其分成批次

delete top(10000) from LMP_DayAhead where interval < @threeDayCutoffDate
delete top(30000) from LMP_RealTime where interval < @threeDayCutoffDate
delete top(20000) from LMP_RealTimeIntegrated where interval < @threeDayCutoffDate
delete top(50000) from ZonalMCP where interval < @threeDayCutoffDate
delete top(1000) from SyncJob where synctime < @threeDayCutoffDate
从LMP_DayAhead中删除top(10000),其中间隔<@Threeday截止日期
从LMP_RealTime中删除top(30000),其中间隔<@Threeday截止日期
从LMP_RealTimeIntegrated中删除top(20000),其中间隔<@三天截止日期
从ZonalMCP中删除顶部(50000),其中间隔小于三天截止日期
从SyncJob中删除顶部(1000),其中synctime<@Threeday截止日期
其中每个顶部(X)的设计覆盖约1天的价值

最后,在凌晨1:00和1:20安排额外的事务日志备份,并在凌晨12:50、1:10和1:30运行此作业,每个批从中提取1天的数据。中间的事务日志备份将在下次运行时保持日志干净


这是一般策略,但您可以调整它以满足您的需要。

啊,太好了!那是票@Paul,@Remus-我不认为简单地将其分为多个批次就能避免日志变满。@cyberwiki:如果事务被分为多个批次,那么无论采用何种现有的日志重用方法(备份日志、简单恢复模型),都可以完成其工作并回收日志。对于一个长事务,无论是备份还是简单的恢复都不能解决日志增长的问题。@Remus-你没有抓住要点。日志在备份之前无法回收,因此,简单地将其分解并不能解决问题。你还是一次成功。关键是必须备份日志才能重用空间,否则就无法从备份和日志中完全重建数据库(如果它能够回收未备份的事务)。我只支持分区截断解决方案。当你的删除相当“无目标”时,这是唯一的方法。嘿,你在一家电力公司工作!酷。看看分区。。。这就是路。