首先,通过转而使用 datetime2 和微秒级的 DATEDIFF,我已经解决了我遇到的实际问题。但我仍然对我所看到的行为感到惊讶,所以......
我正在尝试诊断某些 SQL 的性能问题,并且我有像这样循环的代码来测试它:
DECLARE @timer datetime = NULL
DECLARE @diff int = 0
DECLARE @total int = 0
WHILE(<condition>)
BEGIN
SET @timer = SYSDATETIME()
<select statement under test>
SET @diff = DATEDIFF(MILLISECOND, @timer, SYSDATETIME())
SET @total = @total + @diff
END
SELECT @total
但是我得到的总数是负!?
这到底是怎么回事?
我会理解最终的结果是 @total = 0
;这就是说增量为 <1 毫秒(或者足够接近计时器的分辨率报告),因此我最终会得出大量 0 的总和。
但是 DATEDIFF 可能会返回负数,这似乎存在很大的问题!
我进一步检查并确认 @diff
变量确实返回 -1
甚至 -2
。
什么给出了?
最佳答案
SYSDATETIME
返回精度为 7
位的 datetime2
。
您将其分配给datetime
变量,精度约为每秒1/300
。因此它可以向上舍入(或向下舍入,但向上舍入是这里的原因)。
尝试
DECLARE @SYSDATETIME DATETIME2 = '2017-04-15 14:49:36.001999'
DECLARE @timer DATETIME = @SYSDATETIME;
DECLARE @diff INT = DATEDIFF(MILLISECOND, @timer, @SYSDATETIME);
SELECT @timer AS [@timer],
@diff AS [@diff];
这会返回
+-------------------------+-------+
| @timer | @diff |
+-------------------------+-------+
| 2017-04-15 14:49:36.003 | -2 |
+-------------------------+-------+
.001999
舍入为 .003
并且跨越了两个毫秒边界,因此 DATEDIFF(MILLISECOND
返回 -2
code> 比较舍入值和非舍入值时。
关于sql - SYSDATETIME 向后移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43425426/