如何更快地运行此UPDATE查询?

时间:2016-04-15 12:30:46

标签: sql sql-server-2008-r2 sql-update inner-join between

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)

我在下面有这个查询,在表F_SUPPORT_WEB中有3亿行要更新,我无法运行它,每次我都会收到事务日志问题。 我认为运营商之间是关键,但我不知道如何优化运营商。

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:1)

您希望在循环上运行更新。当您尝试一次更新所有这些记录时,它必须在发生错误时将所有这些记录复制到事务日志中,以便它可以回滚更改。如果您批量更新,则不会遇到该问题。见下文

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

答案 1 :(得分:1)

如果您的日志表驱动器不足以支持该单个事务,则需要将其分解为多个事务。我有一个类似的问题并进行测试,直到我找到了一个最佳位置(为我更新了100,000行)。保持循环直到所有记录都完成。您只需修改查询即可。

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 

您可能希望首先添加一个位置,以查看是否要更新不必要的记录。

答案 2 :(得分:-1)

  1. 使用dim.ids创建临时表Dim。
  2. 使用DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid,仅将id插入临时表DIM中。
  3. 与临时表进行连接(WEB.date_creation BETWEEN DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid)