为什么 WHERE 子句中的硬编码日期比相同日期作为参数提供更快的性能?
Why hard-coded dates in WHERE clause gives faster performance then same dates as a parameters?
如果我将日期放在 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
我需要将此查询作为存储过程,在不降低性能的情况下使用日期参数的最佳方法是什么?
因为你的变量声明为datetime
。这具有更高的数据类型优先级。因此,您要将 DueDate
列显式转换为 date
,然后再次转换为 datetime
。
对您的变量使用 date
,您应该会看到相同的性能。更好的是,如果类型已经正确,请不要 CAST
您的日期列。
我使用以下查询在我的数据库上进行了模拟
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
选项来摆脱参数嗅探。
如果我将日期放在 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
我需要将此查询作为存储过程,在不降低性能的情况下使用日期参数的最佳方法是什么?
因为你的变量声明为datetime
。这具有更高的数据类型优先级。因此,您要将 DueDate
列显式转换为 date
,然后再次转换为 datetime
。
对您的变量使用 date
,您应该会看到相同的性能。更好的是,如果类型已经正确,请不要 CAST
您的日期列。
我使用以下查询在我的数据库上进行了模拟
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
选项来摆脱参数嗅探。