我正在寻找最有效(性能最佳)的方法来检查日期字段是否为当前日期。目前我们使用的是:
SELECT COUNT(Job) AS Jobs
FROM dbo.Job
WHERE (Received BETWEEN DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0)
AND DATEADD(d, DATEDIFF(d, 0, GETDATE()), 1))
我正在寻找最有效(性能最佳)的方法来检查日期字段是否为当前日期。目前我们使用的是:
SELECT COUNT(Job) AS Jobs
FROM dbo.Job
WHERE (Received BETWEEN DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0)
AND DATEADD(d, DATEDIFF(d, 0, GETDATE()), 1))
WHERE
DateDiff(d, Received, GETDATE()) = 0
编辑:正如在本答案的评论中指出的那样,这不是一个理想的解决方案。也请查看本主题中的其他答案。
如果您只想查找接收日期为今天的所有记录,并且有未来接收日期的记录,则您所做的方法(非常非常轻微)是错误的。。。因为Between操作符允许等于结束边界的值,所以您可能会得到接收日期=到明天午夜的记录...
如果不需要在接收方面使用索引,则您只需要检查与当前日期时间的日期差是否为0即可...
Where DateDiff(day, received, getdate()) = 0
这个谓词显然不是SARGable,所以它不能使用索引...如果这是查询的问题,那么假设您不能有未来的接收日期,我会改用以下方法代替...
Where Received >= DateAdd(day, DateDiff(Day, 0, getDate()), 0)
如果接收日期可以在未来,则您可能已经尽可能地高效...(除了将Between更改为>= 和 <)
DateDiff(day, received, getdate())
,因为它会强制对表中的每一行进行计算,造成CPU资源浪费。 - ErikE如果你想要更好的性能,你需要直接命中索引,而不需要每行数据都进行CPU等操作。因此,我建议先计算范围,然后使用简单的WHERE查询。我不知道你正在使用哪个数据库,但在SQL Server中,以下代码可以实现此功能:
// ... where @When is the date-and-time we have (perhaps from GETDATE())
DECLARE @DayStart datetime, @DayEnd datetime
SET @DayStart = CAST(FLOOR(CAST(@When as float)) as datetime) -- get day only
SET @DayEnd = DATEADD(d, 1, @DayStart)
SELECT COUNT(Job) AS Jobs
FROM dbo.Job
WHERE (Received >= @DayStart AND Received < @DayEnd)
这基本上是最好的方法。 你可以将DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0)和DATEADD(d, DATEDIFF(d, 0, GETDATE()), 1)放入变量中,然后使用它们,但我认为这不会提高性能。
我不确定你如何定义“最好”,但那个方法可以正常工作。
然而,如果这个查询是你要重复运行的内容,你应该摒弃get_date()函数,并直接用编程语言中的一个字面日期值替代。尽管它们的输出每24小时只会更改一次,get_date()、current_date()等等都是非确定性函数,这意味着如果你的关系数据库管理系统(RDMS)支持查询缓存,它可能会将这个查询无效化。
怎么样?
WHERE
DATEDIFF(d, Received, GETDATE()) = 0
通常我会使用Tomalak建议的解决方案,但如果你真的需要更好的性能,最好的选择可能是添加一个额外的索引字段ReceivedDataPartOnly - 该字段将存储没有时间部分的数据,然后使用查询。
declare @today as datetime
set @today = datediff(d, 0, getdate())
select
count(job) as jobs
from
dbo.job
where
received_DatePartOnly = @today
将两个日期转换为相同的格式后进行比较,例如以下格式。
where CONVERT(varchar, createddate, 1) = CONVERT(varchar, getdate(), 1);