SQL Query处理日期参数的方式不同

时间:2012-02-23 16:30:30

标签: sql sql-server sql-server-2008 tsql

所以我们有一个简单的查询,它运行时连接到几个表,我们约会这个数据。这些查询构成了我们数据仓库负载的一部分,对时间至关重要。当我们使用where子句中的日期更改为连接到日期为的临时表时,我们注意到执行速度和执行计划存在巨大差异。所以:

    Declare @StartDate DateTime = Cast(Floor(Cast(GetDate() AS FLOAT))AS DateTime)
    Declare @EndDate DateTime = GetDate()

    Select *
    From Table A 
           Inner Join Table B
                On A.A = B.A
    Where A.Date Between @StartDate AND @EndDate

查询的简化版本,但在大约50秒内返回11k行。

    Declare @StartDate DateTime = Cast(Floor(Cast(GetDate() AS FLOAT))AS DateTime)
    Declare @EndDate DateTime = GetDate()

    Select @StartDate StartDate, @EndDate EndDate
    Into #Dates

    Select *
    From Table A 
           Inner Join Table B
                On A.A = B.A
           Inner Join #Dates
                On A.Date Between StartDate AND EndDate

返回相同的11k行但是亚秒。执行计划的差异也很明显,第二个查询充满了嵌套循环,而不是第一个查询中的散列匹配。

我的问题是为什么?为什么50左右的差异?

/ *编辑* /

两个QEP的

1st Query with dates in Where

2nd Query with dates in join

2 个答案:

答案 0 :(得分:3)

我认为你遇到的是一个变量嗅探(或缺乏嗅探)的问题。它的详细解释是here,但它归结为当您使用局部变量时,SQL Server在构建查询计划时没有考虑它们的值。当你使用临时表时,它正在产生一个更高效的计划。

验证这一点的几种方法:

  • 尝试将这些变量转换为查询参数(或sproc paremeters)
  • 尝试添加文章中提到的OPTION(RECOMPILE)。

问题的答案(为什么50年代的差异)纯粹是好QP与坏QP效率之间的差异。

答案 1 :(得分:0)

我认为这是在WHERE子句中使用函数的问题。问题描述为here