Why Datediff between GETDATE() and SYSDATETIME() in milliseconds is always different?

前端 未结 3 1727
Happy的楠姐
Happy的楠姐 2021-01-16 18:31

I am trying to get Datediff between GETDATE() and SYSDATETIME() in milliseconds.

SELECT DATEDIFF(ms, GETDATE() , SYSDA         


        
相关标签:
3条回答
  • 2021-01-16 18:50

    This difference is a good example of the difference between PRECISION and RESOLUTION (let's leave ACCURACY to one side for the moment). GETDATE() returns a DATETIME with (apparently) a PRECISION to the millisecond, but, if you put it in a tight loop, you'll find the next different value returned is several milliseconds later; it can only return about 300 different values each second, as its RESOLUTION is only to about 3 or 4 milliseconds. read more about this here This is a design feature/compromise of the DATETIME datatype.

    0 讨论(0)
  • 2021-01-16 18:57

    They are two different function calls that can return two different times.

    Additionally GETDATE returns a datetime datatype which only has precision of 3-4 ms whereas SYSDATETIME() returns a datetime2(7) datatype.

    Even if both calls were to return exactly the same time you could see the issue that you are experiencing due to rounding.

    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*/
    

    The other answer is incorrect that if you substitute in GETDATE() the function is only called once as can be demonstrated from the below.

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

    When running a loop on my windows XP desktop with GETDATE() and SYSDATETIME I can also see results that indicate that something else might be going on as well though. Perhaps calling a different 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 
    

    Example results below

    +-----------------------------+-----------------------------+-----+
    |             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 |
    +-----------------------------+-----------------------------+-----+
    

    The rows of interest are

    | 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 |
    

    This discrepancy is too large to be a rounding issue and can't just be a timing issue with a delay between calling the two functions as the issue exists on more than one row that GETDATE reports 10:16:03.26X whereas SYSDATETIME reports 10:16:03.250

    0 讨论(0)
  • 2021-01-16 18:59

    They differ because the two functions can't be called simultaneously (at the exact same time). Other processes running can affect the timings. There are dozens of reasons they can differ by varying amounts.

    If you do the same thing with two calls to GetDate() instead, they result in no difference, because the database engine is smart enough to figure out they're the same thing and re-use the results. Using GetDate() and SysDateTime() is different, though, because they're not the same code path (they do different things).

    Think of it this way: If you see 1 + 2 and 1 + 2, it's easy to see that the first expression and the second are the same, and so you only have to do the calculation once. If you change it to 1 + Rand() and 1 + Rand(), you have no way of knowing what the two different calls to Rand() will return, so you have to do the calculations separately.

    0 讨论(0)
提交回复
热议问题