为什么DATEDIFF以毫秒为单位GETDATE()和SYSDATETIME()之间总是有什么不同?

2019-06-27 03:43发布

我试图让Datediff之间GETDATE()SYSDATETIME()以毫秒为单位。

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

我正的结果是0123 。 是什么造成这种差异的原因吗?

看到这个小提琴 。

Answer 1:

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

此外GETDATE返回一个datetime的数据类型仅具有3-4毫秒,而精度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'

当运行与我的Windows XP桌面上循环GETDATE()SYSDATETIME我还可以看到结果表明,别的东西可能会虽然也正在进行。 也许调用不同的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.26XSYSDATETIME报告10:16:03.250



Answer 2:

他们不同,因为这两个功能不能同时调用(在完全相同的时间)。 其他进程运行会影响时序。 有几十个,他们可以通过不同数量不同的原因。

如果你有两个调用做同样的事情GetDate()代替,它们会导致没有任何区别,因为数据库引擎是足够聪明弄清楚他们是同样的事情,再利用的结果。 使用GetDate()SysDateTime()是不同的,但是,因为他们没有相同的代码路径(他们做不同的事情)。

想想这样说:如果你看到1 + 21 + 2 ,可以很容易地看到,第一表达式,第二个是相同的,所以你只需要做计算一次。 如果您将其更改为1 + Rand()1 + Rand()你有没有知道什么到两个不同的调用方式Rand()将返回,所以你必须单独做计算。



Answer 3:

这种差异是精度和分辨率之间的差异的一个很好的例子(让我们离开精度一面的时刻)。 GETDATE()返回(显然)一个精确到毫秒一个DATETIME,但是,如果你把它放在一个紧密的循环,你会发现返回的下一个不同的价值是几毫秒后; 它只能返回每个第二约300个不同的值,因为它的分辨率只有约3或4毫秒。 阅读更多关于此这里这是DATETIME数据类型的设计功能/妥协。



文章来源: Why Datediff between GETDATE() and SYSDATETIME() in milliseconds is always different?