代码之家  ›  专栏  ›  技术社区  ›  Phil Gan

对数百万行的更新查询将填充事务日志

  •  0
  • Phil Gan  · 技术社区  · 16 年前

    作为下一个版本的一部分,我需要更新数百万行,但是这样做会填充事务日志并失败。我有一些想法,但我不是SQL专家,所以我确信会有一些我不知道的问题。

    相关要点:

    1. 我需要将一个脚本移交给操作团队,因此需要一个不需要手动干预的T-SQL方法。
    2. 显然,事务日志每15分钟就被回收一次。(我已经考虑过用一个trick-catch编写一个循环 WAITFOR DELAY '00:15:00' 如下图所示)
    3. (编辑) 除了数据,我不能修改任何东西。
    4. (编辑) 将外键列更改为其他现有键是一个简单的更新。

    谢谢,

    菲尔

    DECLARE
        @AffectedRows int
    
    SET @AffectedRows = 0
    
    WHILE @AffectedRows < @RowsToUpdate
    BEGIN
        BEGIN TRY
            BEGIN TRAN
            -- Do some updates  
            SET @AffectedRows = @AffectedRows + @@RowCount
            COMMIT TRAN
        END TRY
        BEGIN CATCH
            PRINT ERROR_MESSAGE()
            WAITFOR DELAY '00:15:00'
        END CATCH
    END
    
    PRINT @AffectedRows
    
    3 回复  |  直到 16 年前
        1
  •  2
  •   Phil Gan    16 年前

    最后,我编写的示例效果最好;事务日志的完整错误会被捕获,15分钟的时间足以使日志被回收。

    DECLARE 
        @AffectedRows int 
    
    SET @AffectedRows = 0 
    
    WHILE @AffectedRows < @RowsToUpdate 
    BEGIN 
        BEGIN TRY 
            BEGIN TRAN 
            -- Do some updates   
            SET @AffectedRows = @AffectedRows + @@RowCount 
            COMMIT TRAN 
        END TRY 
        BEGIN CATCH 
            PRINT ERROR_MESSAGE() 
            WAITFOR DELAY '00:15:00' 
        END CATCH 
    END 
    
    PRINT @AffectedRows
    
        2
  •  1
  •   Sam Saffron James Allen    16 年前

    几点/想法:

    1. 您可以将事务日志扩展到您想要的任何大小,这样它就不会填充事务日志。
    2. 如果事务日志增长过多,则可以始终备份数据库并截断日志。
    3. 您可以批量处理数据(一次处理一百万个)
    4. 您可以将数据复制到工作表中,然后在处理完成后将其重命名。
        3
  •  0
  •   Meff    16 年前

    您正在重新创建nibbling删除/更新:)

    看看这种方法,你可以做比一行更大的块:

    http://www.sqlservervideos.com/video/nibbling-deletes/

    http://sqladvice.com/blogs/repeatableread/archive/2005/09/20/12795.aspx