简体   繁体   中英

How can I run this UPDATE query faster?

UPDATE 
    WEB 
SET 
    WEB.ID_D_SUPPORT = DIM.ID_D_SUPPORT 
FROM 
    dbo.F_SUPPORT_WEB WEB
INNER JOIN 
    dbo.D_SUPPORT DIM 
    ON WEB.id_support = DIM.id_support 
    AND (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)

I have this query below with 300 million rows in the table F_SUPPORT_WEB to update, I am unable to run it, each time I do I get a transaction log issue. I think the between operator is the key, but I don't know how to optimize it.

Can someone help me ?

You'll want to run updates on a loop. When you try to update all those records at once, it has to copy all of them to the transaction log in case of an error so it can roll back the changes. If you do updates in batches, you won't run into that issue. See below

SELECT 1 --Just to get a @@ROWCOUNT established
WHILE (@@ROWCOUNT > 0)
BEGIN
    UPDATE TOP (5000000) WEB --Change this number to however many you want to update at a time
    SET WEB.ID_D_SUPPORT = DIM.ID_D_SUPPORT 
    FROM dbo.F_SUPPORT_WEB WEB
    INNER JOIN dbo.D_SUPPORT DIM ON WEB.id_support = DIM.id_support 
               AND (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)
    WHERE WEB.ID_D_SUPPORT != DIM.ID_D_SUPPORT --Don't update records that have already been updated, otherwise the loop will run forever
END

If your log table drive isn't big enough to support that single transaction, you need to break it up into multiple transactions. I had a similar issue and tested until I found a sweet spot (100,000 rows updated for me). Keep looping until all records are done. You could do so by simply modifying your query.

UPDATE WEB 
SET WEB.ID_D_SUPPORT = DIM.ID_D_SUPPORT 
FROM dbo.F_SUPPORT_WEB WEB
INNER JOIN dbo.D_SUPPORT DIM ON WEB.id_support = DIM.id_support 
   AND (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)
WHERE WEB.ID_D_SUPPORT <> DIM.ID_D_SUPPORT 

You might want to add that where in the first place to see if you are updating unnecessary records.

  1. create temp table Dim with dim.ids.
  2. bulk insert only with id into temp table DIM with DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid.
  3. make a join with temp table without (WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)

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