为什么GETDATE()和SYSDATETIME()之间的Datediff在几毫秒内总是不同?

时间:2012-08-18 04:51:08

标签: sql-server-2008 datediff getdate sysdatetime

我想以毫秒为单位在DatediffGETDATE()之间获取SYSDATETIME()

SELECT DATEDIFF(ms, GETDATE() , SYSDATETIME());        

我得到的结果是0123。这种差异的原因是什么?

See this fiddle

3 个答案:

答案 0 :(得分:9)

它们是两个不同的函数调用,可以返回两个不同的时间。

此外GETDATE返回datetime数据类型,其精度仅为3-4 ms,而SYSDATETIME()返回datetime2(7)数据类型。

即使两个电话都返回完全相同的时间,您也可以看到由于四舍五入而遇到的问题。

DECLARE @D1 DATETIME2 = '2012-08-18 10:08:40.0650000'
DECLARE @D2 DATETIME = @D1 /*Rounded to 2012-08-18 10:08:40.067*/
SELECT DATEDIFF(ms, @D1 , @D2) /*Returns 2*/

另一个答案是错误的,如果你在GETDATE()中替换该函数只被调用一次,如下面所示:

WHILE DATEDIFF(ms, GETDATE() , GETDATE()) = 0 
PRINT 'This will not run in an infinite loop'

使用GETDATE()SYSDATETIME在我的Windows XP桌面上运行循环时,我还可以看到表明其他内容可能正在进行的结果。也许调用不同的API。

CREATE TABLE #DT2
  (
     [D1] [DATETIME2](7),
     [D2] [DATETIME2](7)
  )

GO

INSERT INTO #DT2
VALUES(Getdate(), Sysdatetime())

GO 100

SELECT DISTINCT [D1],
                [D2],
                Datediff(MS, [D1], [D2]) AS MS
FROM   #DT2

DROP TABLE #DT2 

以下示例结果

+-----------------------------+-----------------------------+-----+
|             D1              |             D2              | MS  |
+-----------------------------+-----------------------------+-----+
| 2012-08-18 10:16:03.2500000 | 2012-08-18 10:16:03.2501680 |   0 |
| 2012-08-18 10:16:03.2530000 | 2012-08-18 10:16:03.2501680 |  -3 |
| 2012-08-18 10:16:03.2570000 | 2012-08-18 10:16:03.2501680 |  -7 |
| 2012-08-18 10:16:03.2600000 | 2012-08-18 10:16:03.2501680 | -10 |
| 2012-08-18 10:16:03.2630000 | 2012-08-18 10:16:03.2501680 | -13 |
| 2012-08-18 10:16:03.2630000 | 2012-08-18 10:16:03.2657914 |   2 |
| 2012-08-18 10:16:03.2670000 | 2012-08-18 10:16:03.2657914 |  -2 |
| 2012-08-18 10:16:03.2700000 | 2012-08-18 10:16:03.2657914 |  -5 |
| 2012-08-18 10:16:03.2730000 | 2012-08-18 10:16:03.2657914 |  -8 |
| 2012-08-18 10:16:03.2770000 | 2012-08-18 10:16:03.2657914 | -12 |
| 2012-08-18 10:16:03.2800000 | 2012-08-18 10:16:03.2814148 |   1 |
+-----------------------------+-----------------------------+-----+

感兴趣的行是

| 2012-08-18 10:16:03.2600000 | 2012-08-18 10:16:03.2501680 | -10 |
| 2012-08-18 10:16:03.2630000 | 2012-08-18 10:16:03.2501680 | -13 |

这种差异太大而不能成为一个舍入问题,并且不能仅仅是一个时间问题,因为问题存在于GETDATE报告10:16:03.26X SYSDATETIME的多行上,因此调用这两个函数之间存在延迟} 10:16:03.250报告{{1}}

答案 1 :(得分:1)

它们不同,因为无法同时调用这两个函数(在同一时间)。运行的其他进程可能会影响计时。他们可以根据不同的数量而有所不同。

如果你通过两次调用GetDate()来做同样的事情,那么它们没有区别,因为数据库引擎很聪明,可以弄清楚它们是同一个东西并重新使用结果。但是,使用GetDate()SysDateTime()是不同的,因为它们不是相同的代码路径(它们执行不同的操作)。

这样想:如果你看到1 + 21 + 2,很容易看出第一个表达式和第二个表达式是相同的,所以你只需要这样做计算一次。如果您将其更改为1 + Rand()1 + Rand(),则无法知道对Rand()的两次不同调用将返回什么,因此您必须单独进行计算。

答案 2 :(得分:-1)

这种差异是PRECISION和RESOLUTION之间差异的一个很好的例子(让我们暂时将ACCURACY留给一方)。 GETDATE()返回一个带有(显然)PRECISION的DATETIME到毫秒,但是,如果你把它放在一个紧密的循环中,你会发现返回的下一个不同的值是几毫秒之后;它每秒只能返回大约300个不同的值,因为它的分辨率只有大约3或4毫秒。 read more about this here这是DATETIME数据类型的设计特性/折衷方案。