2015-09-28 100 views
0

更新表中的值,如果數據沒有在表B中的以下UPDATE語句也正是我想要它做的事:SQL Server 2012中 - 嘗試使用JOIN

UPDATE [dbo].[Person] 
SET [IsUpdated] = 0 
FROM [Person] p 
WHERE p.IsUpdated = 1 
    and p.PersonID NOT IN (SELECT DISTINCT q.PersonID FROM [DeletionQueue] d, [Queue] q 
         WHERE d.fkQueueID = q.QueueID) 

然而,當我運行估計此聲明的執行計劃,我看到我的處理時間的70%被NOT IN SELECT語句消耗。我更願意使用某種JOIN語句來獲得相同的結果。

我試圖用許多不同的方式創建聲明,但最接近我已經能夠複製上述聲明是一個給我與我正在尋找的完全相反的結果(即如果我在Person表中有兩個人,IsUpdated = 1,這兩個人在隊列表(QueueID)中都有一個入口,但是隻有人B在DeletionQueue表(fkQueueID)中,那麼Person表中的人A的記錄應該只有IsUpdated更改爲0)。目前,當我嘗試一條JOIN語句時,人員B被更新並且人員A不被更新。

如果需要,我可以使用該語句,但在此應用程序中性能非常關鍵。有任何想法嗎?

+0

在DeletionQueue.fkQueueID和Queue.QueueID列上有索引嗎? –

+0

我在DeletionQueue.fkQueueID和Queue.QueueID列上都有索引。 – MyLilMulePepe

回答

1

您可以嘗試使用NOT EXISTS代替:

UPDATE [dbo].[Person] 
    SET [IsUpdated] = 0 
FROM [Person] p 
WHERE 
    p.IsUpdated = 1 
    AND NOT EXISTS(
     SELECT 1 
     FROM [DeletionQueue] d 
     INNER JOIN [Queue] q 
      ON q.fkQueueID = q.QueueID 
     WHERE q.PersonId = p.PersonId 
    ) 

根據這一article亞倫貝特朗:

爲在一定條件下不 表A中查找所有行的模式存在表B,NOT EXISTS通常是你最好的 的選擇。但是,一如既往,您需要在自己的環境中測試這些模式,使用您的模式,數據和硬件,並將其與您自己的工作負載混合在一起。

+0

謝謝你的迴應Felix。如果我無法找到一種不使用SELECT語句的方法,我肯定會使用NOT EXISTS而不是NOT IN,因爲這將有助於提高性能。但是,我的70%的時間仍在SELECT查詢上。 – MyLilMulePepe

+0

你的意思是'NOT IN'中的'SELECT'查詢嗎?嘗試刪除「DISTINCT」子句。 –

+0

其實,我的意思是在'NOT EXISTS'中的代碼片段中的'SELECT'查詢。我仍然認爲這將是我最好的選擇。再次感謝。 – MyLilMulePepe