为什么选择Top子句可能会导致长时间的成本

smw*_*dia 16 sql sql-server sql-server-2008-r2

以下查询需要永远完成.但如果我删除前10条款,它会很快完成.big_table_1和big_table_2是2个表,有10 ^ 5条记录.

我曾经相信顶级条款会减少时间成本,但显然不在这里.为什么???

select top 10 ServiceRequestID
from 
(
    (select * 
     from  big_table_1
     where big_table_1.StatusId=2
    ) cap1
    inner join
      big_table_2 cap2
    on cap1.ServiceRequestID = cap2.CustomerReferenceNumber
    )
Run Code Online (Sandbox Code Playgroud)

use*_*017 13

关于同一主题还有其他stackoverflow讨论(底部的链接).正如上面的评论中所指出的,它可能与索引和优化器混淆并使用错误的索引有关.

我的第一个想法是你正在从(select*....)执行select top serviceid,并且优化器可能难以将查询推送到内部查询并使用索引.

考虑将其重写为

select top 10 ServiceRequestID  
from  big_table_1
inner join big_table_2 cap2
on cap1.servicerequestid = cap2.customerreferencenumber
and big_table_1.statusid = 2
Run Code Online (Sandbox Code Playgroud)

在您的查询中,数据库可能正在尝试合并结果并返回它们,然后将其限制为外部查询中的前10位.在上面的查询中,数据库只需要在合并结果时收集前10个结果,从而节省了大量时间.如果servicerequestID被索引,它肯定会使用它.在您的示例中,查询正在查找已以虚拟的无索引格式返回的结果集中的servicerequestid列.

希望有道理.虽然假设优化器应该采用我们放入SQL的任何格式并找出每次返回值的最佳方法,但事实是我们将SQL放在一起的方式可以真正影响在某些步骤中执行某些步骤的顺序. D B.

无论ORDER BY如何,SELECT TOP都很慢

为什么在SQL Server中的索引列上执行top(1)会变慢?


Jav*_*tos 5

我对像你这样的查询有类似的问题。已排序但没有 top 子句的查询用了 1 秒,前 3 个相同的查询用了 1 分钟。

我看到在顶部使用一个变量它按预期工作。

您的案例代码:

declare @top int = 10;

select top (@top) ServiceRequestID
from 
(
    (select * 
     from  big_table_1
     where big_table_1.StatusId=2
    ) cap1
    inner join
      big_table_2 cap2
    on cap1.ServiceRequestID = cap2.CustomerReferenceNumber
    )
Run Code Online (Sandbox Code Playgroud)