Does SQL Server optimize DATEADD calculation in select query?

后端 未结 3 1630
轮回少年
轮回少年 2020-12-19 17:44

I have a query like this on Sql Server 2008:

DECLARE @START_DATE DATETIME
SET @START_DATE = GETDATE()

SELECT * FROM MY_TABLE
WHERE TRANSACTION_DATE_TIME >         


        
3条回答
  •  梦毁少年i
    2020-12-19 17:49

    SQL Server functions that are considered runtime constants are evaluated only once. GETDATE() is such a function, and DATEADD(..., constant, GETDATE()) is also a runtime constant. By leaving the actual function call inside the query you let the optimizer see what value will actually be used (as opposed to a variable value sniff) and then it can adjust its cardinality estimations accordingly, possibly coming up with a better plan.

    Also read this: Troubleshooting Poor Query Performance: Constant Folding and Expression Evaluation During Cardinality Estimation.

    @Martin Smith

    You can run this query:

    set nocount on;
    declare @known int;
    select @known = count(*) from sysobjects;
    declare @cnt int = @known;
    while @cnt = @known
        select @cnt = count(*) from sysobjects where getdate()=getdate()
    select @cnt, @known;
    

    In my case after 22 seconds it hit the boundary case and the loop exited. The inportant thing is that the loop exited with @cnt zero. One would expect that if the getdate() is evaluated per row then we would get a @cnt different from the correct @known count, but not 0. The fact that @cnt is zero when the loop exists shows each getdate() was evaluated once and then the same constant value was used for every row WHERE filtering (matching none). I am aware that one positive example does not prove a theorem, but I think the case is conclusive enough.

提交回复
热议问题