【问题标题】:SQL Server: extremely slow results when increasing top by 1SQL Server:将 top 增加 1 时结果极慢
【发布时间】:2015-05-30 20:30:34
【问题描述】:

我有一个使用内连接连接多个视图和一个表的查询。不涉及子查询,所有连接字段都被索引,所有连接都在 int 字段上。在 select 子句中使用“top 342”会导致查询在约 2 秒内执行。但如果我使用相同的查询和“top 343”,查询不会在 7 分钟内完成执行。我尝试了其他几个低于 342 的值,它们也按预期工作。

从查询中删除连接表会导致查询在几秒钟内完成,无论与 top 一起使用的值如何。

我尝试使用全扫描更新表的统计信息,但没有任何改变。

在我使用的相同 SQL 执行上下文中:

DBCC FREEPROCCACHE
GO
CHECKPOINT; 
GO 
DBCC DROPCLEANBUFFERS; 
GO

哪些类型的事情可能会导致执行缓慢?

【问题讨论】:

  • ...我还对表运行了 DBCC CHECKTABLE,没有发现错误
  • 可能主表中的第 343 条记录在连接表上有大量对应的值,因此加载它们需要很长时间,而不是其他的。如果这是真的,那与数量无关;如果这个记录是第一个,那么“TOP 1”也需要很长时间。
  • @Doug 它加入的字段确保了 1:1 的关系

标签: sql-server sql-server-2008


【解决方案1】:

更改TOP 的值将改变row goal

这会对计划的其余部分产生重大影响。您可能会发现TOP 342 恰好生成了一个计划,其中优先使用嵌套循环等非阻塞运算符,但对于TOP 343,SQL Server 的成本计算模型认为使用阻塞运算符(例如消耗整个子树的哈希联接)更便宜首先例如。

您可以尝试使用诸如

之类的结构
SELECT TOP 363 *
FROM your_view
OPTION (FAST 362) 

或者

DECLARE @Top INT = 363

SELECT TOP (@Top) *
FROM   your_view
OPTION (optimize for (@Top = 362))    

但如果无法通过其他方式获得令人满意的计划,这些对我来说将是最后的手段。

另见Inside the Optimizer: Row Goals In Depth

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多