從我可以看到的一切看起來並不像你的問題與索引有關。
關鍵似乎在於你的nvarchar(max)字段包含「大量」數據。考慮SQL執行此更新所需執行的操作。
由於您正在更新的列可能超過8000個字符,因此將其存儲在頁外,這意味着當該列不爲NULL時,需要額外努力讀取此列。
當您運行一批50000更新時,SQL必須將其置於隱式事務中,以便在出現任何問題時能夠回滾。爲了回滾它必須將該列的原始值存儲在事務日誌中。
假設(爲了簡單起見)每列平均包含10,000個字節的數據,這意味着50,000行將包含大約500MB的數據,這些數據必須臨時存儲(以簡單恢復模式)或永久存儲(完全恢復模式)。
無法禁用日誌,因爲它會危及數據庫的完整性。
我在我的狗慢桌面上運行了一個快速測試,運行的批量甚至10,000變得非常慢,但將大小降低到1000行,這意味着臨時日誌大小約爲10MB,工作得很好。
我加載了一個包含350,000行的表格,並標記了50,000個用於更新的表格。這項工作大約在4分鐘內完成,而且由於它線性擴展,因此我應該可以在我的1處理器2GB桌面上大約6小時內在我的狗慢桌面上更新整個5百萬行,因此我期望在您的強大服務器上支持更好通過SAN或其他東西。
您可能希望將更新語句作爲select運行,只選擇主鍵和大型nvarchar列,並確保它按預期運行。
當然,其他用戶可能會鎖定其他用戶鎖定服務器上的存儲或內存中的內容或爭用,但由於您沒有提及其他用戶,因此我將假設您擁有單用戶模式下的DB。
作爲一種優化,您應確保事務日誌位於與數據不同的物理磁盤/磁盤組上,以最大限度地縮短尋道時間。
另請參閱:http://stackoverflow.com/questions/571750/make-sql-server-faster-at-manipulating-data-turn-off-transaction-logging – 2010-06-02 03:22:28
你是如何做'50K批記錄在一次更新?它是否與存儲過程?如果是這樣,你可以把代碼? – Fede 2010-06-02 03:30:10
@ user356004:在重新閱讀時,我不禁想到服務器負載很重或者設置不正確:那些時間看起來非常高。 – 2010-06-02 04:07:59