我需要一些解释,因为我自己找不到(可能是因为我不知道如何搜索)。
我有一个 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
被声明为 datetime
或 varchar
:
declare @datestart datetime
set @datestart = '20161001';
declare @dateend datetime
set @dateend = '20161101';
此子查询在 23-24 秒内执行,整个查询(提醒此子查询在 CTE 中)需要 7-8 分钟,而之前需要 12-15 秒。
有人可以向我解释为什么将日期与变量进行比较会如此显着地增加执行时间吗?也有可能,整个查询花费了这么长时间,因为当 CTE 是一个变量时,它会每次都重新评估它而不是一次?
最佳答案
这个问题很可能是由大家的评论综合造成的:
如果您的 UsageEnd 列不是 datetime 数据类型,而是 varchar,优化器将首先需要将所有值转换为 datetime 类型,以便与变量进行比较。
带有“硬编码常量”的第一个查询已经在 varchar 中,因此优化器能够更快地执行比较。
这两个计划看起来会有所不同,并清楚地指出在哪里可以找到问题。
关于SQL 查询变量与硬编码值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42996207/