Sql-Server-2008-R2

更新聲明卡住了

  • September 13, 2021

我正面臨更新聲明的性能問題。更新時間太長,但是當我對該更新表執行選擇時,它完成得非常快。

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;

sp_whoisactive 結果的螢幕截圖顯示帶有 lck_m_x 等待的 wait_info

在此螢幕截圖中,我試圖UPDATE在 session_id 57 中執行一個,但它被另一個持有我的查詢所需的鎖的會話阻止。您可以在wait_infoandblocking_session_id列中看到這一點,其中顯示LCK_M_X了等待(這是一個排他鎖,通常由另一個UPDATE正在執行的查詢所需要)和 53(另一個持有鎖的會話)。

執行以下查詢後…查詢完成速度非常快。

執行該count(*)查詢可能會確保查詢所需的所有頁面都在記憶體中(這意味著它會更快,因為不必先從磁碟讀取它們)。這可能只是掩蓋了阻塞問題,因為當頁面在記憶體中時阻塞查詢完成得更快。

這是在類似情況下使用的一種方法。更新 30 行表的 1 行中的 1 個屬性時,更新掛起。該表是來自一些更大的表的外鍵引用。通過以下方式診斷:

  1. 打開活動監視器並查看程序部分
  2. 右鍵點擊更新過程
  3. 選擇顯示實時執行計劃

就我而言,在實時執行計劃中看到實時更新的引用表上的行數。這是一個提示,即使有問題的列與外鍵關係無關,SQL 也在掃描這些表(不知道為什麼)。

通過“編輯前 200 行”進行的更新超時。在查詢中執行更新並完成……但花了 4 分鐘。

引用自:https://dba.stackexchange.com/questions/256663