2012-03-29 75 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