为什么GETDATE()和SYSDATETIME()之间的Datediff(以毫秒为单位)总是不同



我正在尝试以毫秒为单位在GETDATE()SYSDATETIME()之间获取Datediff

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

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

看看这把小提琴。

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

此外,GETDATE返回精度仅为3-4ms的datetime数据类型,而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在WindowsXP桌面上运行循环时,我还可以看到一些结果,表明可能也发生了其他事情。也许调用不同的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 的多行上

它们不同是因为这两个函数不能同时调用(完全同时调用)。其他正在运行的进程可能会影响计时。它们可能因数量不同而不同,原因有很多。

如果您对GetDate()的两个调用执行相同的操作,它们不会产生任何差异,因为数据库引擎足够聪明,可以发现它们是相同的,并重复使用结果。然而,使用GetDate()SysDateTime()是不同的,因为它们不是同一个代码路径(它们做不同的事情)。

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

这个差异是PRECISION和RESOLUTION之间差异的一个很好的例子(让我们暂时把准确性放在一边)。GETDATE()返回一个DATETIME,(显然)PRECISION为毫秒,但是,如果你把它放在一个紧密的循环中,你会发现下一个不同的返回值是在几毫秒后;它每秒只能返回大约300个不同的值,因为它的RESOLUTION只有大约3或4毫秒。在这里阅读更多信息这是DATETIME数据类型的一个设计特性/折衷。

相关内容

  • 没有找到相关文章

最新更新