2013-03-04 40 views
2

我想有条件地执行MERGE语句,因此它不会尝试匹配整个目标表。 我原来的说法是有点这样的:SQLServer - 具有条件的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),和 '条件' 要像[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”没有按” t加快执行时间?
  • 如果“行匹配”是更长的过程,为什么设置INT字段会加快执行时间?
+0

请将一些(实际)执行计划作为.sqlplan发布。他们让我们看到到底发生了什么问题。是的,我认为你的结果很好奇,应该进行调查。 – usr 2013-03-05 23:45:53

回答

0

根据SQL Server文档:

” ...不要尝试通过在ON子句中的目标表中筛选出列,如通过指定AND NOT target_table.column_x =以提高查询性能值。这样做可能会返回意外和不正确的结果 .. *

第一个查询是无效的。如果你更新固定lenght列你不应该花时间的结果纳入考虑。

(INT,日)有w不应该是“行溢出数据超过8 KB”的情况。当您使用nvarchar(4000)并给出较差的查询性能时,可能会发生这种情况。

我们现在不介绍合并函数是如何工作的以及它如何处理数据。所以只有这个函数的开发者可以给你答案你的问题。

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

Marcin Pazgier

+0

我们实际上*可以*使用执行计划在里面窥视。 – usr 2013-03-05 23:45:29