2015-10-19 91 views
0

我有一個存儲過程在Microsoft SQL Server 2012數據庫上運行,它經常(但並非總是)在某個點掛起。當我執行特定的更新查詢本身時,它運行良好,但是如果它在整個過程中執行,此後沒有任何反應。這是它出錯:SQL查詢掛起沒有錯誤(並行子查詢?)

UPDATE dbo.gesch_gzp 
    SET red_ges=1 
    WHERE uitg_verr_id IN (
     SELECT uitg_verr_id 
     FROM dbo.gzp_flagging_2 
     WHERE flag BETWEEN 2200 AND 2299 
      AND flag IN (
       SELECT flag 
       FROM flagging 
       WHERE lts=1 
       ) 
      ) 

注視等待任務(dm_os_waiting_tasks)我強烈地得到的印象是它是與parallellism,由於具有相同的session_id,但不同exec_context_id那裏等待多個子進程彼此。 因此,我已經嘗試添加選項(MAXDOP 1),並添加了一個DISTINCT到第一個選擇,但沒有與所需的效果(重新啓動存儲過程後,它掛在完全相同的點)。

UPDATE dbo.gesch_gzp 
    SET red_ges=1 
    WHERE uitg_verr_id IN (
     SELECT DISTINCT(uitg_verr_id) 
     FROM dbo.gzp_flagging_2 
     WHERE flag BETWEEN 2200 AND 2299 
      AND flag IN (
       SELECT flag 
       FROM flagging 
       WHERE lts=1 
       ) 
      ) 
    OPTION(MAXDOP 1) 

所以我想知道是否有一種方法來重寫這個存儲過程,以防止它掛起。複雜的事情是,這個有問題的更新查詢恰好在一個很長的程序的末尾,這個程序需要24小時才能執行。並且執行更新查詢本身不會再現問題(這需要幾分鐘),所以這使測試變得困難。

+0

聽起來像是阻塞問題。你可以在SP應該運行時檢查阻塞嗎? –

+0

@ Dave.Gugg,不確定你的意思,但查詢dm_os_waiting_tasks會導致一些進程具有相同的session_id,並被具有相同session_id的其他進程阻止。例如:'session_id = 76,\t exec_context_id = 3,\t wait_time = 78435004,\t wait_type = CXPACKET,blocking_session_id = 76,blocking_exec_context_id = 1,resource_description =「exchangeEvent id = Pipe4a858fe20 WaitType = e_waitPipeGetRow nodeId = 10」'。但是我必須說,這是在添加Maxdop之前,添加此選項後在服務器重新啓動期間丟失了什麼。 – shardeman

回答

0

您可以重寫UPDATE語句是這樣的:

UPDATE gg 
SET  gg.red_ges = 1 
FROM dbo.gesch_gzp gg 
     INNER JOIN dbo.gzp_flagging_2 gf2 ON gg.uitg_verr_id = gf2.uitg_verr_id 
     INNER JOIN flagging f ON gf2.flag = f.flag 
WHERE gf2.flag BETWEEN 2200 AND 2299 
     AND f.lts = 1 

不過,我不認爲這一定解決您的問題。您需要檢查懸掛時實際發生的情況。如果您沒有設置任何阻止監控,請在查詢掛起時運行exec sp_who2開始,並檢查BlkBy列以查看哪些SPID被阻止。一旦你有了SPID,你就可以找到什麼SQL阻止它並重構你的SQL。

+0

將嘗試此操作,但需要一些時間才能完成。最後一次,我還在懸掛時嘗試了'sp_who2',並且在那裏有5個與此SPID相關的項目,但它們都是BlkBy空的(。),但blocking_sessions不是空的(請參閱上面的註釋)。 – shardeman

+0

運行整個程序,它像一個魅力(現在)。如果/當問題再次出現時,我將更詳細地研究sp_who2。現在感謝。 – shardeman