这些在效率上是否相等

时间:2013-02-08 13:02:25

标签: sql-server sql-server-2012

我从不质疑以下两个脚本之间的效率差异:

DateKey的类型为INT

1

DECLARE @StartDate  INT = 20130101,
        @EndDate    INT = 20130201

SELECT  UserAccountKey,
        income_LT = SUM(ISNULL(income,0.0)) 
INTO    #x
FROM    WH.dbo.xxx x
WHERE   x.DateKey > = @StartDate
        AND x.DateKey < @EndDate
GROUP BY    UserAccountKey

执行上述操作是:

enter image description here

2

SELECT  UserAccountKey,
        income_LT = SUM(ISNULL(income,0.0)) 
INTO    #x
FROM    WH.dbo.xxx x
WHERE   x.DateKey > = 20130101
        AND x.DateKey < 20130201
GROUP BY    UserAccountKey

以下是2号的执行计划: enter image description here

1.要快得多(2秒与80秒相比) - 这是否符合预期?为什么呢?

1 个答案:

答案 0 :(得分:3)

在第一个查询中,它使用变量。这些值在编译时是未知的,因此它根据通用估计产生计划。在第二个,它根据实际参数值编译计划。

通用猜测比计算知道特定值的计划更好的事实表明您的统计数据可能需要更新。

可能最后一次更新时,如果有任何行与WHERE DateKey > = 20130101 AND DateKey < 20130201谓词匹配,但现在有很多行。

这是ascending date columns

的常见问题

See also this question and answers on the dba site

修改这可以在此处的计划中看到

enter image description here

线条的粗细表示行数。计算标量左侧的细线显示估计的行数(计算标量for the reasons here通常不显示实际行计数)。计算标量中的非常粗的行和排序中的非常粗的行表示实际的行数。这两者显然非常不同。

除了选择不合适的计划(带有嵌套循环连接的串行)之外,这个糟糕的估计还意味着当查询请求内存授予不足时(由警告三角形显示),排序溢出到光盘。