【问题标题】:SQLServer - MERGE with condition is slow, even an "always false" conditionSQL Server - 合并条件很慢,甚至是“总是错误”的条件
【发布时间】:2013-02-18 19:23:10
【问题描述】:

我想有条件地执行 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)s 之外的任何其他类型都会导致语句执行得更快。

总之,我不明白的事情是:

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

【问题讨论】:

  • 请将一些(实际)执行计划发布为 .sqlplan。它们使我们能够准确地看到出了什么问题。是的,我认为你的结果很奇怪,应该进行调查。

标签: sql sql-server-2008 merge


【解决方案1】:

根据 sql server 文档:

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

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

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

我们现在不知道合并函数如何在内部工作以及它如何处理数据。所以大概只有这个功能的开发者才能回答你的问题。

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

马辛·帕兹吉尔

【讨论】:

  • 我们实际上可以使用执行计划窥视内部。
猜你喜欢
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-22
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 1970-01-01
相关资源
最近更新 更多