我根据等于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 - 平均273毫秒
4 - 1745ms平均值
测试的样本量为~300,000
这有什么理由吗?第一种选择真的是最好的选择吗?
编辑:更改测试值以反映为300k记录每次运行10次的测试。除了Tim Schmelter在下面提到的DATEADD/DATEDIFF
方法之外,更改结果以显示所有结果非常相似。这似乎是效率最低的。
答案 0 :(得分:4)
我会说#3是最好的选择。这是我的理由。
你已经完成了表演工作,所以我不会重做它。您更新的数字显示选项1-3非常相似,因此我们可以将性能放在一边,除了排除#4。
一旦表现得到解决,它就会达到最佳实践和可读性。 #1肯定是大多数代码和最难阅读所以我会排除这一点。同样的理由适用于已经排除的#4。
这给我们留下了#2和#3。我的选择是#3,因为CAST是SQL标准的一部分,比CONVERT更便携。因此,无论何时您不需要CONVERT的特殊功能,我都建议您始终使用CAST。
答案 1 :(得分: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