在SQL Server中从datetime字段中删除时间部分时,哪种方法提供了最佳性能?
a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
or
b) select cast(convert(char(11), getdate(), 113) as datetime)
第二种方法确实发送了更多的字节,但这可能没有转换速度那么重要。
两者看起来也都非常快,但在处理数十万行或更多行的时候,速度可能会有所不同。
此外,是否可能有更好的方法来消除SQL中datetime的时间部分?
就我个人而言,如果处理SQL Server 2005(或更低版本),几乎总是使用用户定义函数,然而,应该注意的是,使用UDF有特定的缺点,特别是如果将它们应用于WHERE子句(参见下面和对这个答案的评论了解更多细节)。如果使用SQL Server 2008(或更高版本)-请参见下面。
事实上,对于我创建的大多数数据库,我都是在一开始就添加这些UDF,因为我知道早晚有99%的可能性会用到它们。
我为“仅限日期”和“仅限时间”创建了一个(尽管“仅限日期”是迄今为止使用最多的一个)。
以下是一些与日期相关的UDF的链接:
基本SQL Server日期,时间和DateTime函数
只获取日期函数
最后一个链接显示了不少于3种获取datetime字段部分日期的不同方法,并提到了每种方法的优缺点。
If using a UDF, it should be noted that you should try to avoid using the UDF as part of a WHERE clause in a query as this will greatly hinder performance of the query. The main reason for this is that using a UDF in a WHERE clause renders that clause as non-sargable, which means that SQL Server can no longer use an index with that clause in order to improve the speed of query execution. With reference to my own usage of UDF's, I'll frequently use the "raw" date column within the WHERE clause, but apply the UDF to the SELECTed column. In this way, the UDF is only applied to the filtered result-set and not every row of the table as part of the filter.
当然,最好的方法是使用SQL Server 2008(或更高版本)并分离出您的日期和时间,因为SQL Server数据库引擎随后会本地提供单独的日期和时间组件,并且可以有效地独立查询这些组件,而不需要UDF或其他机制来从复合datetime类型中提取日期或时间部分。
这是来自另一个重复问题的另一个答案:
SELECT CAST(CAST(getutcdate() - 0.50000004 AS int) AS datetime)
这个魔数方法比DATEADD方法执行得稍微快一些。(看起来像~10%)
百万记录数轮的CPU时间:
DATEADD MAGIC FLOAT
500 453
453 360
375 375
406 360
但请注意,这些数字可能无关紧要,因为它们已经非常快了。除非我有100,000或更多的记录集,否则我甚至无法让CPU时间读数高于零。
考虑到DateAdd就是为了这个目的,而且更健壮,我建议使用DateAdd。