【问题标题】:Why hard-coded dates in WHERE clause gives faster performance then same dates as a parameters?为什么 WHERE 子句中的硬编码日期比与参数相同的日期提供更快的性能?
【发布时间】:2026-02-10 06:00:02
【问题描述】:

如果我将日期放在 WHERE 子句(第一个查询)或将相同的日期作为参数(第二个查询),为什么性能会有如此巨大的差异

--------/* Execution time 3 sec*/ 
   select 
            tblNoteDiaries.DueDate,
            col2,
            col3
    from MyTable 
    where CAST(tblNoteDiaries.DueDate as date) <= cast(getdate()as date) and cast( tblNoteDiaries.DueDate as date) >= CAST('2017-09-29' as DATE)

--------/* Execution time 10 sec*/    
    declare     @DateFrom datetime = '2017-09-29',
                @DateTo datetime = '2017-10-05'
    select 
            tblNoteDiaries.DueDate,
            col2,
            col3
    from    MyTable 
    where   CAST(tblNoteDiaries.DueDate as date)  >= @DateFrom   and cast( tblNoteDiaries.DueDate as date) <= @DateTo 

我需要将此查询作为存储过程,在不降低性能的情况下使用日期参数的最佳方法是什么??

【问题讨论】:

  • 你看到执行计划有什么不同吗?
  • 最有可能是参数嗅探。执行计划会给你一个线索。

标签: sql-server performance tsql database-administration


【解决方案1】:

我使用以下查询在我的数据库上进行了模拟

select sum(PrinBal)
from fpc
where SnapshotDt >= '2017-06-01' and SnapshotDt <= '2017-06-30'
go

declare @sd date = '2017-06-01'
declare @ed date = '2017-06-30'
select sum(PrinBal)
from fpc
where SnapshotDt >= @sd and SnapshotDt <= @ed
go

并检查执行计划。第一次查询为 48%,第二次查询为 52%。

然后我在第二个查询中添加了option(recompile),然后两者的百分比完全相同

declare @sd date = '2017-06-01'
declare @ed date = '2017-06-30'
select sum(PrinBal)
from fpc
where SnapshotDt >= @sd and SnapshotDt <= @ed
option(recompile)
go

正如尼克所说,它是参数嗅探。

您可以使用更新的统计信息或为查询和存储过程使用RECOMPILE 选项来摆脱参数嗅探。

【讨论】:

    【解决方案2】:

    因为你的变量被声明为datetime。这具有更高的数据类型优先级。因此,您将DueDate 列显式转换为date,然后再次转换为datetime

    date 用于您的变量,您应该会看到相同的性能。更好的是,如果类型已经正确,请不要CAST您的日期列。

    【讨论】:

    • 我测试了日期和日期时间类型,但没有发现任何区别。
    最近更新 更多