2016-04-15 123 views
0
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

不會期望遇到*事務日誌問題*,因此解決這個問題可能是一個好主意。你的問題是什麼? –

回答

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 

您可能想在第一個位置添加以查看是否更新不必要的記錄。

+0

謝謝,「哪裏」改變了一切! (y) – imanebz

+0

@imanebz太好了!如果在你的場景中可能的話,不要忘記檢查NULL。 – UnhandledExcepSean

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. 創建臨時表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)