SQLServer - MERGE条件很慢,甚至是“总是错误的”条件

时间:2013-03-04 16:19:50

标签: sql sql-server-2008 merge

我想有条件地执行MERGE语句,因此它不会尝试匹配整个目标表。 我原来的陈述有点像这样:

MERGE [target_table] USING [table_source]
ON (([target_table].[ID] = [table_source].[ID]) AND (condition))
WHEN MATCHED THEN UPDATE
SET [table_source].[_strField1] = [table_source].[_strField2];

注意:假设'_strField'被输入为nvarchar(4000),'condition'就像[target_table]。[_ strField8] ='sometext'。

但是我在documentation中遇到了"...Do not attempt to improve query performance by filtering out rows in the target table in the ON clause"中的以下警告。

所以我的原始查询被改为以下

MERGE [target_table] USING [table_source]
ON (([target_table].[ID] = [table_source].[ID]))
WHEN MATCHED AND (condition) 
THEN UPDATE
SET [table_source].[_strField] = [table_source].[_strField];

问题是,查询现在需要花费更多时间。即使将条件改为“总是假的”,例如 1 = 2 也没有任何帮助。另一方面,设置不同的字段,例如

SET [table_source].[_intField] = [table_source].[_intField];

或除两个nvarchar(4000)以外的任何其他类型导致语句执行得更快。

总而言之,我不明白的是:

  • 如果nvarchar(4000)的数据设置是较长的过程,为什么将条件设置为“1 = 2”不会加快执行时间?
  • 如果“行匹配”是一个较长的过程,为什么设置INT字段会加快执行时间?

1 个答案:

答案 0 :(得分:0)

根据sql server文档:

“...不要通过在ON子句中过滤掉目标表中的行来尝试提高查询性能,例如通过指定AND NOT target_table.column_x = value。这样做可能会返回意外和不正确的结果 .. *

您的第一个查询无效。你不应该考虑时间结果。

如果更新具有固定长度(int,date)的列,则不会出现“超过8 KB的行溢出数据”情况。当您使用nvarchar(4000)并提供较差的查询性能时,可能会出现这种情况。

我们现在不知道合并功能如何在内部工作以及如何处理数据。所以,只有这个功能的开发人员才能给你答案。

我希望我能帮助您解决varchar(4000)性能问题。

Marcin Pazgier