csh*_*hah 9 t-sql sql-server sql-server-2005
我有SQL Server 2005标准Service Pack 2 9.00.4053.00(英特尔X86)
表有近3000万行..
如果我做
SELECT GETDATE(), * FROM
<table>
Run Code Online (Sandbox Code Playgroud)
返回相同的日期和时间值,包括毫秒部分 ..虽然查询花费了超过3分钟才能完成...
我已经读过了
http://sqlblog.com/blogs/andrew_kelly/archive/2008/02/27/when-getdate-is-not-a-constant.aspx
我发布的一个链接(标记答案)表明,在SQL 2005之前,GETDATE是确定性的,尽管SQL 2000 BOL声明GETDATE是不确定的
如果我用数百万行进行更新
UPDATE tableName
SET dateColumn = GETDATE()
Run Code Online (Sandbox Code Playgroud)
我知道你真的想做
DECLARE @DT datetime
SET @DT = GETDATE()
UPDATE table
SET datecol =@DT
Run Code Online (Sandbox Code Playgroud)
我真的很困惑
什么是预期的行为?
考虑到你正在更新一个包含1亿行的表上的日期字符日期列将具有相同的日期和时间(以毫秒为单位)....
Mar*_*ith 10
GetDate()从来都不是确定性的.确定性意味着它在传递相同参数时将始终返回相同的结果.
与此相同,每列rand()评估一次,但一旦评估,对所有行保持相同.
这是比较容易看到这种行为rand()比getdate()
select top 4 rand(), rand()
from sys.objects
Run Code Online (Sandbox Code Playgroud)
回
---------------------- ----------------------
0.0566172633850772 0.431111195699363
0.0566172633850772 0.431111195699363
0.0566172633850772 0.431111195699363
0.0566172633850772 0.431111195699363
Run Code Online (Sandbox Code Playgroud)
如果您尝试以下
select top 10 getdate(), getdate()
from sys.objects
Run Code Online (Sandbox Code Playgroud)
并查看实际执行计划中的ComputeScalar运算符属性,您将看到它GetDate()被评估两次.
注意:在SQL 2000(我不知道)之后,每列而不是每个查询的这种评估行为可能会发生变化,但这不是BOL定义为确定性的含义.
继 Martin Smith 的回答之后,所提到的决定论是 udf 行为的变化。在 SQL Server 2000 中,不能在 udf 中使用 GETDATE。您可以在 SQL Server 2005 中使用。也请参阅此链接
正如 Martin Smith 所说,某些函数是按列、每个查询进行评估的。不是每行。GETDATE 是一个,RAND 是另一个。
如果您确实需要逐行评估 GETDATE,请将其包装在 udf 中。
编辑:
NEWID 在统计上是唯一的。必须逐行对其进行评估,这样就不会在另一行中出现相同的值。因此CHECKSUM(NEWID())生成逐行随机数的技巧......