2012-03-29 169 views
1

我有一張表,TBL1,只有GUID。哪個更快/更好:哪裏更新或合併?

我有另一個表,TBL2,其中主鍵是GUID,它也有一些其他列。我想根據GUID是否在TBL1中更新TBL2表中的某一列。

以下哪個查詢更快和/或更可靠?

MERGE INTO [db].[dbo].[TBL1] AS target 
    USING [db].[dbo].[TBL2] as source 
     ON target.GUID = source.GUID 
    WHEN MATCHED THEN 
     UPDATE SET 
      StatusColumn = 0; 

UPDATE [db].[dbo].[TBL1] 
    SET StatusColumn=0 
    WHERE GUID IN (SELECT GUID FROM [db].[dbo].[TBL2]) 

也許別的東西嗎?

+4

當您嘗試時發生了什麼?執行計劃對兩種表述都說了什麼? – 2012-03-29 20:00:56

+0

*一般*不推薦使用'WHERE IN'。 「WHERE EXISTS」更普遍被接受。但不管怎麼說,MERGE的設計是爲了*更多*而非*更快*。但爲什麼有人會說,爲什麼不自己測試所有的選項? * [另外,請注意,通常不建議使用GUID作爲主鍵。如果你的PK是你的聚簇鍵,你將會像無體的業務一樣分割表 - 因爲GUID不是按順序生成的,所以新條目需要插入表中的隨機位置,而不是在末尾插入。] * – MatBailie 2012-03-29 20:06:49

+0

@Dems - 好建議。我想補充一點,如果你使用Guids作爲主鍵,只需創建它們(或者改變它們)爲非集羣。我們注意到,通過進行這種改變,我們的環境顯着提高了性能 – RQDQ 2012-03-29 20:52:27

回答

3

的這個問題的答案只能來自執行計劃。從您發佈的計劃(http://i.imgur.com/6vB2t.png),我們可以看到如下:

  • IN是生產左加入。這是更高效一點。還有一個優化器的弱點,即使可以,優化器也不會從顯式連接生成半連接。
  • 合併是對行進行排序。這是因爲您可能會從您的加入中獲得重複項!如果這是不可能的,合併會一樣快。
  • 我猜顯式連接版本和合並一樣快。

診斷這個沒有計劃只是猜測。看看這個計劃和/或措施。測量提供了答案,但是該計劃提供了的理解的答案。

+1

+1「只是猜測」。 – 2012-03-29 21:12:03

+0

請記住,執行計劃會隨着統計信息的變化而改變。碎片化,併發性以及其他一些現實世界因素。這不是一個靜態的答案。 – MatBailie 2012-03-29 21:29:33

+0

如果計劃是相同的,沒有特別的理由相信它們可能會發生分歧(無法想到),它就是一個靜態的答案。 – usr 2012-03-29 21:37:54

1

我認爲最快的方法就是使用連接可能是第三個選擇:

UPDATE t1 SET StatusColumn=0 
FROM db.dbo.TBL1 t1 
INNER JOIN db.dbo.TBL2 t2 ON t1.guid = t2.guid 
+0

+1:由於t1中的每條記錄匹配t2中的0或1條記錄,我也認爲這將是最快的選擇。 – MatBailie 2012-03-29 20:11:14

+0

爲什麼會更快?合併等同於您的版本,更新聲明也是如此。誰知道優化器是否能夠生成相同的計劃?我不知道,但我猜*它會。 – usr 2012-03-29 20:33:42

+0

@usr - 它可能會爲所有三個生成相同的計劃,但使用連接是告訴優化器到底想要做什麼的最直接方式。 – 2012-03-29 20:43:04