SQL Batched Delete

后端 未结 9 1892
星月不相逢
星月不相逢 2021-02-20 04:29

I have a table in SQL Server 2005 which has approx 4 billion rows in it. I need to delete approximately 2 billion of these rows. If I try and do it in a single transaction, th

9条回答
  •  生来不讨喜
    2021-02-20 05:06

    Here is my example:

    -- configure script
    -- Script limits - transaction per commit (default 10,000)
    -- And time to allow script to run (in seconds, default 2 hours)
    --
    DECLARE @MAX INT
    DECLARE @MAXT INT
    --
    -- These 4 variables are substituted by shell script.
    --
    SET @MAX = $MAX
    SET @MAXT = $MAXT
    SET @TABLE = $TABLE
    SET @WHERE = $WHERE
    
    -- step 1 - Main loop
    DECLARE @continue INT
    -- deleted in one transaction
    DECLARE @deleted INT
    -- deleted total in script
    DECLARE @total INT
    SET @total = 0
    DECLARE @max_id INT, @start_id INT, @end_id INT, @interval INT
    SET @interval = @MAX
    SELECT @start_id = MIN(id), @max_id = MAX(id) from @TABLE
    SET @end_id = @start_id + @interval
    
    -- timing
    DECLARE @start DATETIME
    DECLARE @now DATETIME
    DECLARE @timee INT
    SET @start = GETDATE()
    -- 
    SET @continue = 1
    IF OBJECT_ID (N'EntryID', 'U') IS NULL 
    BEGIN
        CREATE TABLE EntryID (startid INT)
        INSERT INTO EntryID(startid) VALUES(@start_id)
    END
        ELSE
    BEGIN
        SELECT @start_id = startid FROM EntryID
    END
    
    
    WHILE (@continue = 1 AND @start_id <= @max_id)
    BEGIN
    
        PRINT 'Start issued:   ' + CONVERT(varchar(19), GETDATE(), 120)
        BEGIN TRANSACTION
            DELETE 
            FROM @TABLE
            WHERE id BETWEEN @start_id AND @end_id AND @WHERE
            SET @deleted = @@ROWCOUNT
        UPDATE EntryID SET EntryID.startid = @end_id + 1
        COMMIT
        PRINT 'Deleted issued: ' + STR(@deleted) + ' records. ' + CONVERT(varchar(19), GETDATE(), 120) 
        SET @total = @total + @deleted
        SET @start_id = @end_id + 1
        SET @end_id = @end_id + @interval
        IF @end_id > @max_id
            SET @end_id = @max_id
    
        SET @now = GETDATE()
        SET @timee = DATEDIFF (second, @start, @now)
        if @timee > @MAXT
        BEGIN
        PRINT 'Time limit exceeded for the script, exiting'
        SET @continue = 0
        END
    --    ELSE
    --    BEGIN
    --      SELECT @total 'Removed now', @timee 'Total time, seconds'   
    --    END
    END
    
    SELECT @total 'Removed records', @timee 'Total time sec' , @start_id 'Next id', @max_id 'Max id', @continue 'COMPLETED? '
    SELECT * from EntryID next_start_id
    
    GO
    

提交回复
热议问题