为什么WHERE子句中的硬编码日期与同一个参数相比,能够提供更快的性能?

为什么WHERE子句中的硬编码日期与同一个参数相比,能够提供更快的性能?

问题描述:

为什么表现如此巨大的差异,如果我把我在WHERE子句(第一查询)日期,如果我把相同的日期作为参数(第二查询)为什么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 

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

+1

你看到执行计划有什么不同吗? – FLICKER

+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选项来摆脱参数嗅探。

+0

太棒了!非常感谢你 !!! – Oleg

因为您的变量被声明为datetime。这具有更高的数据类型优先级。所以你明确地将DueDate列转换为date,然后再转换成datetime

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

+0

我测试了日期和日期时间类型,但没有看到任何区别。 – FLICKER