SQL 查询变量与硬编码值

标签 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 是一个变量时,它会每次都重新评估它而不是一次?

最佳答案

这个问题很可能是由大家的评论综合造成的:

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

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

这两个计划看起来会有所不同,并清楚地指出在哪里可以找到问题。

关于SQL 查询变量与硬编码值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42996207/

相关文章:

php - 在 SQL 中第 n 次执行后,ajax 返回成功

java - 无法从命令提示符使用 JAR 连接到 MS SQL Server 2008,但在 Eclipse 中成功运行

SQL - 从一个表中选择具有相似值但具有不同前缀的所有行

mysql - Codeception DB模块异常

sql-server - 出现 "data too large for variable"错误时如何正确访问 FireDAC 数据集的 VARCHAR(MAX) 参数值?

Sql Server 按多列分组,仅在一列上唯一

mysql - 计算同一列中的多个项目从 2 个表中提取数据 - mysql

mysql - MySQL 中的子查询非常慢

sql - 在 MS SQL Server 数据库中存储未知数据类型

sql - 具有不同时间戳的重复条目