为什么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
我需要这个查询作为存储过程,在不降低性能的情况下利用日期参数的最佳方法是什么?
我模拟了用我下面的数据库查询
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
选项来摆脱参数嗅探。
太棒了!非常感谢你 !!! – Oleg
因为您的变量被声明为datetime
。这具有更高的数据类型优先级。所以你明确地将DueDate
列转换为date
,然后再转换成datetime
。
使用date
作为变量,您应该看到相同的性能。更好的是,如果类型已经正确,请不要输入日期列。
我测试了日期和日期时间类型,但没有看到任何区别。 – FLICKER
你看到执行计划有什么不同吗? – FLICKER
最有可能的参数嗅探。执行计划会给你一个线索。 –