因此,我有一個存儲過程,需要定期更新一個大型表,其中包含大約7000萬條記錄。我通常總是遵循循環更新的標準來避免鎖定我的其他大型表,並且通常我沒有看到性能影響太大。循環SQL Server更新語句的性能不佳
問題: 當我使用循環相比,沒有循環邏輯的原始運行時我看到了10倍或20倍我的執行時間增加。
例如:
如果我運行下面的查詢我會在大約150分鐘更新一次300萬條記錄。
UPDATE [db1].[dbo].[Preferences]
SET LastUpdate = Getdate()
WHERE
LastUpdate >= CAST(CONVERT(Varchar(10), DATEADD(day,-1,GETDATE()), 110) as DateTime)
AND
LastUpdate < CAST(CONVERT(Varchar(10), GETDATE(), 110) as DateTime)
AND (@PreferenceID is null or @PreferenceID = PreferenceID)
這是我的常規更新語句,沒有循環機制。基本上,參數@PreferenceID或者提供了一個ID或留空。根據它,它將更新所有lastUpdate的當前日期或只更新一個preferenceID。在我的測試用例中,我使用了1個preferenceID,因此@PreferenceID正在被填充。
所以當我在這個語句中加入循環時,它花了1.5分鐘到20分鐘。
下面是循環語句:
BEGIN
SET ROWCOUNT 10000
UPDATE [DB1].[dbo].[Preferences]
SET LastUpdate = Getdate()
WHERE
LastUpdate >= CAST(CONVERT(Varchar(10), DATEADD(day,-1,GETDATE()), 110) as DateTime)
AND
LastUpdate < CAST(CONVERT(Varchar(10), GETDATE(), 110) as DateTime)
AND (@PreferenceID is null or @PreferenceID = PreferenceID)
WHILE @@ROWCOUNT > 0
UPDATE [DB1].[dbo].[Preferences]
SET LastUpdate = Getdate()
WHERE
LastUpdate >= CAST(CONVERT(Varchar(10), DATEADD(day,-1,GETDATE()), 110) as DateTime)
AND
LastUpdate < CAST(CONVERT(Varchar(10), GETDATE(), 110) as DateTime)
AND (@PreferenceID is null or @PreferenceID = PreferenceID)
SET ROWCOUNT 0
END
所以我的核心問題是爲什麼我的執行時間增長這麼多隻是做的10K的循環記錄時間?我可以發佈有關表結構的更詳細的信息,但我不確定這是否是一個堅定的規則,與只進行一次完整批量更新相比,執行循環更新的性能會受到影響。
在此先感謝任何人可以提供的建議。
你在每一個更新做檢查點? –
爲什麼不把getdate()保存到一個變量中並使用它呢? –
您是否嘗試過增加50000或100000批量? –