Shm*_*dty 37 sql t-sql sql-server performance sql-server-2008
更好的是,我的意思是它是否以一些非边际数量提高了性能?
也就是说,每次调用时GETDATE()
,服务器返回该值的工作量是多少?
如果我GETDATE()
在存储过程中的许多地方使用,我应该创建一个变量来存储事务的日期吗?
declare @transDate datetime = GETDATE()
Run Code Online (Sandbox Code Playgroud)
基准测试数据非常棒.
编辑我想澄清一下:我主要关注这两种可能性之间的实际性能差异,以及它是否重要.
Gor*_*off 20
[注意:如果你打算回答这个问题,请发表评论解释原因.它已被多次下调,最后ypercube(谢谢)解释了至少一个原因.我无法删除答案,因为它被接受了,所以你不妨帮助改进它.]
根据微软的这种交流,GETDATE()
从查询中的常量切换到SQL Server 2005中的非确定性.回想起来,我认为这不准确.我认为它在SQL Server 2005之前是完全不确定的,然后在SQL Server 2005之后被黑客入侵了一个名为"非确定性运行时常量"的东西.后面的短语实际上似乎意味着"在查询中不变".
(并且GETDATE()
被定义为明确且自豪地非确定性,没有限定词.)
唉,在SQL Server中,非确定性并不意味着为每一行计算一个函数.SQL Server确实使这个问题变得非常复杂和模糊,只有非常少的文档.
实际上,在查询运行时评估函数调用,而不是在编译查询时评估函数调用,并且每次调用查询时其值都会更改.实际上,GETDATE()
只对每个使用它的表达式计算一次 - 在执行时而不是编译时.但是,Microsoft将rand()
其getdate()
置于一个特殊类别,称为非确定性运行时常量函数.相比之下,Postgres没有跳过这样的箍,只是在执行"稳定"时调用具有常量值的函数.
尽管马丁史密斯的评论,SQL Server文档在这个问题上根本不明确 - GETDATE()
被描述为"非确定性"和"非确定性运行时常量",但该术语并未真正解释. 我找到这个术语的地方,例如,文档中的下一行说不要在子查询中使用非确定性函数.这对于"非确定性运行时常量"来说是愚蠢的建议.
我建议甚至在查询中使用带常量的变量,这样你就有了一致的值.这也使得意图非常明确:您希望查询中包含单个值.在单个查询中,您可以执行以下操作:
select . . .
from (select getdate() as now) params cross join
. . .
Run Code Online (Sandbox Code Playgroud)
实际上,这是一个建议,应该只在查询中评估一次,但可能有例外.出现混淆是因为getdate()
在所有不同的行上返回相同的值 - 但它可以在不同的列中返回不同的值.每个表达式getdate()
都是独立评估的.如果您运行,这很明显:
select rand(), rand()
from (values (1), (2), (3)) v(x);
Run Code Online (Sandbox Code Playgroud)
在存储过程中,您可能希望在变量中包含单个值.如果存储过程在午夜过程中运行,并且日期发生变化,会发生什么?这会对结果产生什么影响?
至于性能,我的猜测是日期/时间查找是最小的,并且当查询开始运行时,每个表达式发生一次查询.这不应该是性能问题,而是更多的代码一致性问题.
Tar*_*ryn 18
我的建议是使用变量主要是因为如果你有一个长时间运行的进程,GetDate()
调用之间的值可能会有所不同.
除非您只使用那Date
部分,GetDate()
否则您将确保始终使用相同的值.