sql - 为什么选择 Top 子句会导致长时间成本

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

以下查询需要很长时间才能完成。但如果我删除 top 10 子句,它会很快完成。 big_table_1和big_table_2是2个表,有10^5条记录。

我曾经相信top子句会减少时间成本,但显然不是这样。为什么???

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
    )

最佳答案

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

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

考虑将其重写为

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

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

希望这是有道理的。虽然假设优化器应该采用我们输入 SQL 的任何格式,并找出每次返回值的最佳方式,但事实是,我们将 SQL 组合在一起的方式确实会影响在 SQL 上执行某些步骤的顺序。数据库。

SELECT TOP is slow, regardless of ORDER BY

Why is doing a top(1) on an indexed column in SQL Server slow?

关于sql - 为什么选择 Top 子句会导致长时间成本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9616965/

相关文章:

MySQL拒绝在 `NULL`列中插入 `default null`值

mysql - 按总计 SQL 对周结束数字进行分组;每月;年初至今的数字

sql - 遍历表和字段列表并将它们混合

sql-server-2008-r2 - 当文章发生更改时,DDL 触发器将其从复制中删除

php - 使用 PHP 链接 SQL 表

mysql - 全文索引结合普通索引

sql - 寻求在较大表上调优 Oracle SQL 的技巧和教程

sql-server - 带有分页和计数的 SQL Server 查询

sql-server - SQL Server 查询查找所有当前数据库名称

sql-server - SQL Server 索引 View