为什么查询优化器不优化我的谓词?

时间:2014-08-29 05:33:22

标签: sql-server-2008 tsql query-optimization

我试图理解在谓词中引入变量的影响。我有这个查询

declare @CommentedOnly nvarchar(max)=null

select top 5 * from journalemail je
where @CommentedOnly IS NULL OR je.ID IN (SELECT EmailID FROM EmailComments)

这是实际的计划

enter image description here

我希望过滤器会被优化和删除,因为它始终为null。但是,当我看到计划时,过滤器会增加查询的成本。

有些人可以指导我这是如何工作的吗?

2 个答案:

答案 0 :(得分:2)

存储并重用SQL Server中的查询计划。没有进行分析以确定变量的值确实是常量,因此SQL Server必须生成一个可以重用于变量的所有可能值的计划。

您的示例中的查询计划实际上不会触及表EmailComments,因为Left Semi Join仅检查是否存在至少一行,而该行来自Constant Scan,当{返回一行时{1}}为空。

您可以要求SQL Server使用@CommentedOnly为每次执行生成新计划。您将获得每次执行的编译开销,但变量值保证是它的原因并且优化器使用该知识,因此在您的示例中,它将构建仅包含Clustered Index Scan和Top运算符的计划

option recompile

答案 1 :(得分:0)

如果查看查询计划,它根本没有声称知道空声明 - 它似乎只查看查询。也许存储过程中的类似代码(其保证将设置值与查询耦合)实际上将被优化。在没有设置此类空值的其他上下文中,此分析器可能会打开空间以供查询使用。