我只是想看看是否有更好的方法来执行这样的查询,我认为where子句中的强制转换是瓶颈,但不确定解决它的最佳方法是什么。执行计划中有34%是插入到临时表中,而42%是散列匹配。
SET @StartDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + -12, 0)
SET @EndDate = DATEADD(MILLISECOND, -3, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
where cast(ITF.Date as DATE) BETWEEN CAST(@StartDate as date)
AND CAST(@EndDate as date)
答案 0 :(得分:1)
检查DATETIME
值是否在两个DATE
之间的最合适方法是使用date1 <= datetime AND datetime < date2
,其中date2比要包含的最后日期多一天。
这不需要在datetime列上进行任何强制转换,并且可以处理datetime列包含时间值(例如23:59:59.999999
)的特殊情况,并避免特定的技巧(例如减去3毫秒hack)
WHERE ITF.Date >= CAST(@StartDate as date) AND ITF.Date < CAST(@EndDate as date)
答案 1 :(得分:0)
您发布的部分代码很好,而不是引起任何性能问题的原因。
如果在执行计划中获得哈希匹配,则意味着您可能缺少两个表连接的列上的一个或多个索引。
答案 2 :(得分:0)
根据您查询的其余部分,根据我从SQL 6.5起的经验,消除@StartDate和@EndDate强制转换会加快查询速度。
DECLARE @StartDate Date
DECLARE @EndDate Date
答案 3 :(得分:0)
您似乎想要:
where ITF.Date >= CAST(@StartDate as date) and
ITF.Date < dateadd(day, 1, CAST(@EndDate as date))
Aaron Bertrand's blog“魔鬼之间的共同点”很好地解释了为什么不应该将between
与日期/时间值一起使用。
请注意在结束日期前加上“ 1”。您的代码以及该版本均包含结束日期。