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

问题描述:

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) 

我在下面的查询中有3亿行F_SUPPORT_WEB需要更新,我无法运行它,每次我得到事务日志问题。 我认为运营商之间是关键,但我不知道如何优化它。如何更快地运行此UPDATE查询?

有人可以帮助我吗?

+0

多少索引上的网站的?您可能需要禁用索引,并在更新后强制刷新。 – xQbert

+0

只有一个索引.. – imanebz

+0

不会期望遇到*事务日志问题*,因此解决这个问题可能是一个好主意。你的问题是什么? –

如果你的日志表驱动是没有大到足以支持单次交易,你需​​要把它分解成多个事务。我有一个类似的问题,并进行测试,直到我找到了一个甜蜜点(为我更新了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 

您可能想在第一个位置添加以查看是否更新不必要的记录。

+0

谢谢,“哪里”改变了一切! (y) – imanebz

+0

@imanebz太好了!如果在你的场景中可能的话,不要忘记检查NULL。 – UnhandledExcepSean

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

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. 创建临时表Dim与dim.ids。
  2. 仅将带有id的批量插入临时表DIM与DIM.Date_Deb_Valid AND DIM.Date_Fin_Valid。
  3. 使用临时表的连接,而不(BETWEEN DIM.Date_Deb_Valid和DIM.Date_Fin_Valid WEB.date_creation)