我正在使用ms sql server。我有一个像这样的SQL:
select ... from
(select ... from ... left join .... where ... order by ... offset 0 rows fetch next 50 rows only) a
left join ...
left join ...
当我将50改为20或10时,执行速度很慢,当我使用50时,执行速度不是那么慢,这会导致什么结果呢?
我比较sqlplan,两个图没有区别,除了每个节点中的参数(步骤?)。
另外,我更改了另一个数据库,问题不会发生。
答案 0 :(得分:1)
答案可能与ORDER BY
子句中使用的基础排序算法有关。在获取前10行,20行等之前,首先需要对记录进行排序。出于说明的目的,我们假设ORDER BY
中出现的列上没有索引,并且数据库正在使用分而治之的排序算法,例如mergesort。对于仅提取单行的极端情况,需要运行整个排序算法。这是因为我们不知道单个记录是什么,直到整个记录集被排序。但是,在提取50条记录的情况下,不需要对整个数据集进行排序。相反,一旦我们达到50个记录的块,我们就可以停止那种排序,然后只剩下剩下的50个记录可能需要进一步排序。
实际上,如果您的ORDER BY
子句中的列被编入索引,则上述描述可能会更改。在这种情况下,我们可能只需要遍历B树一次以找到匹配的记录。如果是这样,那么获取一小部分记录到大量记录的性能可能没那么差异。
答案 1 :(得分:0)
执行时间的差异可能来自查询优化器。它可以选择不同的查询计划,例如在10行的情况下切换到嵌套循环连接,但在100的情况下使用合并。
只需比较各种变体的查询执行计划,并查看更改内容。
如果是关于使用的连接类型,您可以看到更新基础表的统计信息是否有助于获得稳定的性能