SQL Server:被GETDATE()所吸引

10

我使用的是 SQL Server 2005 Standard Service Pack 2 9.00.4053.00 (Intel X86) 版本。

表格中有接近 3000 万行数据。

如果我执行

SELECT GETDATE(), * FROM
<table>

包括毫秒的相同日期和时间值被返回,尽管查询需要超过3分钟才能完成...

我已经阅读了:

http://sqlblog.com/blogs/andrew_kelly/archive/2008/02/27/when-getdate-is-not-a-constant.aspx

http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/66507b8b-4a74-44c1-9637-3ab5f75db6a0

我所贴出的其中一个链接(标记为答案)表明,在SQL 2005之前,GETDATE是确定性的,尽管SQL 2000 BOL表示GETDATE是非确定性的。

如果我对数百万行进行更新...

UPDATE tableName
SET dateColumn = GETDATE()

我知道你真的很想做

DECLARE @DT datetime
SET @DT = GETDATE()
UPDATE table
SET datecol =@DT

我真的很困惑

预期的行为会是什么?

  1. 针对我之前发布的 select 语句
  2. update 语句的行为

考虑你正在更新一个有1亿行的表中的日期列,那么日期列是否会有相同的日期和毫秒时间?

2个回答

11

GetDate() 从来不是确定性的。确定性意味着当传入相同的参数时,它将始终返回相同的结果。

rand() 相似,它在每个列上被评估一次,但一旦评估完成,在所有行中都保持不变。

使用 rand()getdate() 更容易观察到这种行为。

select top 4 rand(), rand()
from sys.objects
返回
---------------------- ----------------------
0.0566172633850772     0.431111195699363
0.0566172633850772     0.431111195699363
0.0566172633850772     0.431111195699363
0.0566172633850772     0.431111195699363

如果您尝试以下操作

select top 10 getdate(), getdate()
from sys.objects

如果查看实际执行计划中的ComputeScalar运算符属性,您将看到GetDate()被评估了两次。

注:评估每个列而不是每个查询的行为可能会在SQL 2000之后更改(我不知道),但这不是BOL定义确定性含义的内容。


马丁,为什么NEWID()返回不同的结果? - cshah
@cshah - 很好的问题,我不知道答案! - Martin Smith
@cshah,@Martin Smith:请查看我的NEWID答案。 - gbn
1
+1:我通过在两个getdate()之间插入几千个RAND()函数,成功验证了您提到的行为(SQL Server 2008)。https://dev59.com/Jm025IYBdhLWcg3wYFCH#6036783 - StriplingWarrior

4
继承Martin Smith的回答,所指的确定性是udf行为的变化。在SQL Server 2000中,您不能在udf中使用GETDATE。但在SQL Server 2005中可以使用。也请参考此链接 如Martin Smith所说,有些函数是按列、按查询计算的,而不是按行计算的。GETDATE就是其中之一,RAND是另一个。
如果确实需要逐行评估GETDATE,则将其包装在udf中。
编辑:
NEWID在统计上是唯一的。必须逐行评估,以便您不会在另一行中看到相同的值。因此使用CHECKSUM(NEWID())技巧生成逐行随机数...

谢谢,但为什么不使用NEWID的行为不同?选择 top 4 newid(),newid() from sys.objects - cshah
现在我明白了,如果你想要随机返回行,则使用 ORDER BY NEWID(),因此 newid() 是不同的... - cshah
更新操作行为相同吗?即 UPDATE tableName SET dateColumn = GETDATE()。好的,它是相同的...太笨了 :-( - cshah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接