Sql-Server-2008-R2
更新聲明卡住了
我正面臨更新聲明的性能問題。更新時間太長,但是當我對該更新表執行選擇時,它完成得非常快。
UPDATE mo SET mo.RNCNEID = ts.RNCID, mo.SiteNEID = ts.SiteID, mo.SectorNEID = ts.SectorID FROM COPS_UMTS_HUAWEI.PER.tHuawei_CELL_Ncell_DY_HR AS mo INNER JOIN COPS_UMTS_HUAWEI.Aggregation.tsector AS ts ON mo.rncname = ts.rncname AND mo.cellid = ts.cid AND ts.VendorID = 6 AND ts.TechnologyID = 2 WHERE mo.RNCNEID IS NULL;
執行以下查詢後:
SELECT COUNT(*) FROM COPS_UMTS_HUAWEI.PER.tHuawei_CELL_Ncell_DY_HR WITH (NOLOCK) WHERE RNCNEID IS NULL;
…它完成得非常快。
更新需要很長時間,但是當我在該更新表上進行選擇時,它的完成速度非常快。
如果
UPDATE
查詢花費了很長時間,但該SELECT
部分在單獨執行時速度很快,那麼一個可能的原因是由於另一個會話持有不兼容的鎖而導致該UPDATE
部分被阻塞。您可以在查詢執行時檢查這一點
UPDATE
,例如,執行sp_WhoIsActive
:EXEC sp_WhoIsActive;
在此螢幕截圖中,我試圖
UPDATE
在 session_id 57 中執行一個,但它被另一個持有我的查詢所需的鎖的會話阻止。您可以在wait_info
andblocking_session_id
列中看到這一點,其中顯示LCK_M_X
了等待(這是一個排他鎖,通常由另一個UPDATE
正在執行的查詢所需要)和 53(另一個持有鎖的會話)。執行以下查詢後…查詢完成速度非常快。
執行該
count(*)
查詢可能會確保查詢所需的所有頁面都在記憶體中(這意味著它會更快,因為不必先從磁碟讀取它們)。這可能只是掩蓋了阻塞問題,因為當頁面在記憶體中時阻塞查詢完成得更快。
這是在類似情況下使用的一種方法。更新 30 行表的 1 行中的 1 個屬性時,更新掛起。該表是來自一些更大的表的外鍵引用。通過以下方式診斷:
- 打開活動監視器並查看程序部分
- 右鍵點擊更新過程
- 選擇顯示實時執行計劃
就我而言,在實時執行計劃中看到實時更新的引用表上的行數。這是一個提示,即使有問題的列與外鍵關係無關,SQL 也在掃描這些表(不知道為什麼)。
通過“編輯前 200 行”進行的更新超時。在查詢中執行更新並完成……但花了 4 分鐘。