2011-10-13 38 views
3

我想知道下面的正確解決方案是什麼。在生產中運行更新語句時鎖定行

我在T-SQL中有一個UPDATE語句,需要作爲日常任務運行。該過程將更新一個表中的一個位列。受影響的行數約爲30,000。

在T-SQL

UPDATE TABLE_NAME 
SET BIT_FIELD = [dbo].[FUNCTION](TABLE_NAME.ID) 
WHERE -- THIS ISN'T RELEVANT 

確定真或假基本上運行幾個支票和打約3其他表中的功能的僞版本。目前該程序需要大約30分鐘的時間才能在我們的開發環境中運行和更新30,000行。我期待這在生產上翻一番。

我遇到的問題是間歇性地鎖定了TABLE_NAME表。如果我以1000的批次運行它,似乎可以,但如果我增加它,它似乎運行良好,但最終表鎖定。唯一的解決方法是取消導致沒有行被更新的查詢。

請注意,該過程未包含在TRANSACTION中。

如果我在單獨的UPDATE聲明中運行每個更新,這個問題會解決嗎?在實時環境中更新大量記錄時,什麼是一個好的解決方案?

任何幫助將不勝感激。

謝謝!

+0

您是否已將鎖升級爲表鎖? –

+0

函數是否也從TABLE_NAME讀取? – JStead

+0

嗨馬丁和JStead。感謝您及時的回覆。 回答馬丁的問題..我沒有。當我認爲發生鎖定時,我可以通過針對不同的列運行簡單選擇來測試這一點嗎? JStead - 函數確實從TABLE_NAME讀取。 謝謝兩位 –

回答

1

就你而言,SQL Server Optimizer可能確定需要表鎖來執行表的更新。您應該對查詢執行返工,以避免發生此表鎖或對用戶造成的影響較小。因此,以一種實際的方式,這意味着:(a)加快查詢速度並(b)確保表格不會鎖定。
我個人會考慮以下幾點:
1.在您的表上創建聚簇索引和非聚簇索引以提高查詢的性能。
2.看看是否可以不使用函數,而是使用連接,它們通常要快得多。
3.分解多個部分的更新並單獨執行這些部分。你可能在'where'子句中有一個'或'的定義,這是一個很好的分割點,但是你也可以考慮創建一個光標來循環遍歷整個表,並一次執行一條記錄的更新。

+0

或者設置一個更新前1000條記錄的批處理過程,然後更新下一個1000條記錄等。另外,OP應該意識到這些類型的函數像遊標一樣逐行運行,這就是更新需要這麼長時間的原因。用連接替代函數或可能的情況下,可能會加速到鎖定不是一個問題。需要30分鐘的日常任務是慢得令人無法接受的。 – HLGEM