SQL查询变量与硬编码值

时间:2017-03-24 09:51:23

标签: sql sql-server sql-server-2008

我需要解释一些东西,因为我自己找不到(可能是因为我不知道如何搜索它)。

我有一个带有一些公用表表达式的SQL Server查询,其中一个CTE正在根据日期选择数据,用户不是空的,例如。

WHERE 
    "dummy"."UsageEnd" >= '20161001' 
    AND "dummy"."UsageEnd" < '20161101' 
    AND "Users"."Login" IS NOT NULL

在该表单中,此查询在~2秒内执行,但我需要将日期更改为参数,因为此查询将非常常见地执行。但如果我把它改为:

WHERE  
    "dummy"."UsageEnd" >= @start 
    AND "dummy"."UsageEnd" < @end 
    AND "Users"."Login" IS NOT NULL

@start@end声明为datetimevarchar

declare @datestart datetime
set @datestart = '20161001';

declare @dateend datetime
set @dateend = '20161101';

此子查询在23-24秒内执行,整个查询(作为提示此子查询在CTE中)需要7-8分钟,之前需要12-15秒。

有人可以向我解释为什么将日期与变量进行比较会大大增加执行时间吗?也有可能,整个查询花了这么长时间,因为当CTE是一个变量时,它会每次重新评估它而不只是一个吗?

2 个答案:

答案 0 :(得分:0)

问题可能是由每个人的评论组合引起的:

如果您的UsageEnd列不是datetime数据类型,而是varchar,优化器首先需要将所有值转换为日期时间类型,以便与变量进行比较。

带有“硬编码常量”的第一个查询已经在varchar中,因此优化器能够更快地执行比较。

这两个计划看起来都不同,并明确指出在哪里可以找到问题。

答案 1 :(得分:0)

当运算符组合了两种不同数据类型的表达式时,数据类型优先级的规则指定具有较低优先级的数据类型转换为具有较高优先级的数据类型。如果转换不是受支持的隐式转换,则会返回错误。 MSDN