在 SQL Server 中删除日期时间的时间部分的最佳方法

问题描述:

从 SQL Server 中的日期时间字段中删除时间部分时,哪种方法可提供最佳性能?

Which method provides the best performance when removing the time portion from a datetime field in SQL Server?

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

b) select cast(convert(char(11), getdate(), 113) as datetime)

第二种方法确实会多发送几个字节,但这可能不如转换速度重要.

The second method does send a few more bytes either way but that might not be as important as the speed of the conversion.

两者看起来也都非常快,但在处理数十万或更多行时速度可能会有所不同?

Both also appear to be very fast, but there might be a difference in speed when dealing with hundreds-of-thousands or more rows?

另外,是否有更好的方法来摆脱 SQL 中日期时间的时间部分?

Also, is it possible that there are even better methods to get rid of the time portion of a datetime in SQL?

严格来说,方法 a 是最不占用资源的:

Strictly, method a is the least resource intensive:

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

已证明在相同的总持续时间一百万行中占用更少的 CPU 密集度被手上有太多时间的人证明:SQL Server 中从日期+时间获取日期的最有效方法?

Proven less CPU intensive for the same total duration a million rows by someone with way too much time on their hands: Most efficient way in SQL Server to get a date from date+time?

我在其他地方也看到过类似的测试,结果也类似.

I saw a similar test elsewhere with similar results too.

我更喜欢 DATEADD/DATEDIFF 因为:

I prefer the DATEADD/DATEDIFF because:

编辑,2011 年 10 月

对于 SQL Server 2008+,您可以 CAST 到 date,即 CAST(getdate() AS date).或者只是使用 date 数据类型所以没有 time 删除.

For SQL Server 2008+, you can CAST to date i.e. CAST(getdate() AS date). Or just use date datatype so no time to remove.

编辑,2012 年 1 月

这是一个灵活的例子:需要在sql server中按四舍五入的时间或日期数字计算

编辑,2012 年 5 月

不要在 WHERE 子句等中不加考虑地使用它:向列添加函数或 CAST 会使索引使用无效.请参阅此处的第 2 点常见 SQL 编程错误

Do not use this in WHERE clauses and the like without thinking: adding a function or CAST to a column invalidates index usage. See number 2 here Common SQL Programming Mistakes

现在,这确实有一个更高版本的 SQL Server 优化器版本正确管理 CAST 的示例,但是通常这将是一个坏主意......

Now, this does have an example of later SQL Server optimiser versions managing CAST to date correctly, but generally it will be a bad idea ...

编辑,2018 年 9 月,日期时间 2

DECLARE @datetime2value datetime2 = '02180912 11:45' --this is deliberately within datetime2, year 0218
DECLARE @datetime2epoch datetime2 = '19000101'

select DATEADD(dd, DATEDIFF(dd, @datetime2epoch, @datetime2value), @datetime2epoch)