简体   繁体   中英

How do I speed up the batch of update queries over the table with 2 million rows?

I have around 2 million update queries

UPDATE table1 
SET WIN = 'A-9-0-9999-00000-00000-0000' 
WHERE WIN= 'A-0-9-0000-999999-000000'

Now I have around 2 millions update queries which I paste in SQL window and run at once but it's taking around 1 hour for each system (I have same db over different servers).

The table1 itself has 2 million rows.

And I have removed Index from WIN column which is of type varchar .

How can I speed this up?

Update:

TO let you know, I have around 2 million update queries like the one above with different values.

 UPDATE table1 
    SET WIN = 'A-9-0-9999-00000-00000-0000' 
    WHERE WIN= 'A-0-9-0000-999999-000000'

.

.
.
.
.
.
.
.
.
.
.
 UPDATE table1 
    SET WIN = 'G-6-H-9999-00000-00000-0000' 
    WHERE WIN= 'A-1-9-0000-999999-000000'

and I am running all at once.

I think that you should convert your updates to inserts and execute it by batches.

SET XACT_ABORT ON;
SET NOCOUNT ON;

CREATE TABLE #Replaces  (
    ReplaceId INT      NOT NULL IDENTITY PRIMARY KEY,
    OldWIN    CHAR(27) NOT NULL,
    NewWIN    CHAR(27) NOT NULL,
    TargetId  INT
);

INSERT INTO #Replaces (OldWIN, NewWIN)
VALUES('A-9-0-9999-00000-00000-0000', 'A-0-9-0000-999999-000000')
-- ...
-- ...
INSERT INTO #Replaces (OldWIN, NewWIN)
VALUES('G-6-H-9999-00000-00000-0000', 'A-1-9-0000-999999-000000')

-- Scan for Id in table1 once.
UPDATE Replaces
SET TargetId = table1.Id
FROM #Replaces AS Replaces
INNER JOIN table1 ON table1.WIN = Replaces.OldWIN

DECLARE @BATCH_SIZE INT = 500;

DECLARE @batch    TABLE (
    ReplaceId INT      NOT NULL PRIMARY KEY,
    TargetId  INT      NOT NULL,
    NewWin    CHAR(27) NOT NULL
);
DECLARE @maxId    INT = 0;

WHILE 1 = 1
BEGIN
    BEGIN TRY
        INSERT INTO @batch (ReplaceId, TargetId, NewWIN)
        SELECT TOP (@BATCH_SIZE) ReplaceId, TargetId, NewWIN
        FROM #Replaces
        WHERE ReplaceId > @maxId
        ORDER BY ReplaceId;

        IF @@ROWCOUNT = 0 BREAK;

        UPDATE table1
        SET WIN = Batch.NewWin
        FROM @batch AS Batch
        INNER JOIN table1 ON table1.Id = Batch.TargetId

        SELECT @maxId = MAX(ReplaceId) FROM @batch;

        DELETE @batch;
    END TRY BEGIN CATCH
        SELECT ERROR_MESSAGE = ERROR_MESSAGE();
        BREAK;
    END CATCH
END

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM