6

我根据date等于字段的字段返回行datetime。它们显然只在格式为时直接匹配,dd/MM/yyyy = dd/MM/yyyy 00:00:00但我希望忽略时间。

我尝试了 3 种方法,它们都有效,但我想知道什么是最好的。

1 -CONVERT(varchar(10),MyDate,103) = CONVERT(varchar(10),MyDateTime,103))

2 -MyDate = CONVERT(date,MyDateTime)

3 -MyDate = CAST(MyDateTime AS date)

4 -MyDate = DATEADD(dd, DATEDIFF(dd, 0, MyDateTime), 0)

对我来说,#1 应该是最慢的,转换为字符串然后使用字符串比较肯定效率最低。但在测试中它是最快的!以下是我的测试:

1 - 303ms 平均

2 - 284 毫秒平均

3 - 273ms 平均

4 - 1745ms 平均

测试来自约 300,000 的样本量

是否有一个原因?第一个选项真的是最好的选择吗?

编辑:更改了测试值以反映每个 300k 记录运行 10 次的测试。DATEADD/DATEDIFF除了下面提到的 Tim Schmelter 方法之外,更改结果以显示所有内容都非常相似。这似乎是迄今为止效率最低的。

4

2 回答 2

4

我会说#3是最好的选择。以下是我的理由。

表演工作你已经完成了,我就不重做了。您更新的数字显示选项 1-3 非常相似,因此我们可以将性能放在一边,除了排除 #4。

一旦确定了性能,就开始关注最佳实践和可读性。#1 对于大多数代码来说绝对是最难阅读的,所以我会排除它。同样的原因也适用于已经排除的#4。

这给我们留下了#2和#3。我选择#3,因为 CAST 是 SQL 标准的一部分,并且比 CONVERT 更便携。因此,我建议始终使用 CAST,只要您不需要 CONVERT 的特殊功能。

于 2015-02-10T01:58:06.230 回答
1

如果MyDate是参数,那么还有第五个选项:

检查是否MyDateTime介于[MyDate, MyDate + 1 DAY). 如果该列上有索引,则此查询可以使用索引查找而不是索引扫描。

DECLARE @MyDate1 AS DATETIME = '2015-01-01'              -- 2015-01-01 00:00:00
DECLARE @MyDate2 AS DATETIME = DATEADD(DAY, 1, @MyDate1) -- 2015-01-02 00:00:00
SELECT ... WHERE MyDateTime >= @MyDate1 AND MyDateTime < @MyDate2
于 2015-05-14T13:17:32.643 回答