TOP子句减慢了查询速度

时间:2016-12-07 17:09:00

标签: sql sql-server sql-server-2008-r2

我有2个查询:一个有TOP子句,一个没有。结果完全相同,但TOP子句的结果明显变慢。为什么会这样?

服务器:Microsoft SQL Server 2008 R2(SP2)

查询1 - 常规

insert into #Buffer (details, persistentID, productID, [date])
select de.details, lg.databaseID % 1000, lg.productID, lg.readDateTime
from Log lg with (nolock)
join LogDetails de with (nolock)
    on lg.logID = de.logID
where @startDate <= readDateTime and readDateTime < @endDate
  • CPU时间:173,640 ms
  • 经过时间:34,700毫秒
  • Execution Plan

查询2 - TOP子句

insert into #Buffer (details, persistentID, productID, [date])
select top (@count) de.details, lg.databaseID % 1000, lg.productID, lg.readDateTime
from Log lg with (nolock)
join LogDetails de with (nolock)
    on lg.logID = de.logID
where @startDate <= readDateTime and readDateTime < @endDate

注意@count是结果集的大小。

奇怪的是,查询2的CPU时间是查询1的一半,但查询2的经过时间是查询1的3倍。

1 个答案:

答案 0 :(得分:2)

基于此:Inside the Optimizer: Row Goals In Depth来自Paul White

当您向SQLServer提出查询时,它会假设您将消耗查询生成的所有行。但是有时,当您引入TOP和EXISTS运算符时,SQL服务器将尝试查找第一行尽快,这有时会导致较少的最优计划。在你的情况下,它会导致嵌套循环计划..

你可能会问为什么这一行目标,无法优化......下面是保罗怀特对此的解释。

  

为行限制查询生成优化查询计划所涉及的挑战,同时保留完整结果查询的良好通用优化性能,比简单地用嵌套循环替换散列或合并连接迭代器更复杂。使用设计用于识别特定方案的特定代码来满足计划根目录中的TOP的查询将是相当简单的。但是,在更一般的情况下,这种方法会错过更广泛的计划优化机会。

     

可以在查询声明的多个位置多次指定TOP子句:在最外层范围内(如示例中所示);在子查询中;或者在一个公用表格中 - 所有这些都可能是任意复杂的。 FAST'n'查询提示也可用于要求优化器更喜欢快速生成第一个'n'行的计划,而不限制整体返回的总行数,如TOP的情况。作为最后一个例子,考虑逻辑半连接(例如用EXISTS引入的子查询)共享整个主题:应该优化它以快速找到第一个匹配的行。

     

SQL Server查询优化器提供了一种满足所有这些要求的方法,它引入了“行目标”的概念,该行目标只是在计划的特定点上建立了一些“目标”行。

因此,在您的情况下,要克服此ROWGOAL限制,您可以使用提示重写下面的查询

insert into #ViewCountBuffer (details, persistentID, productID, [date])
 select top (@count) details, databaseID % 1000, productID, readDateTime
 from Log ld with (nolock)
 HASH join LogDetails de with (nolock)
  on ld.logID = de.logID
 where @startDate <= readDateTime and readDateTime < @endDate

以下是相同主题的堆栈Exchange上的相关主题,..

https://dba.stackexchange.com/questions/157353/wrapping-query-in-if-exists-makes-it-very-slow

https://dba.stackexchange.com/questions/126235/if-exists-taking-longer-than-embedded-select-statement

https://dba.stackexchange.com/questions/24832/how-and-why-does-top-impact-an-execution-plan