SQL Server:OFFSET FETCH在TOP WHERE执行搜索时执行扫描?

时间:2017-01-19 11:39:18

标签: sql sql-server pagination

我收到了以下两个问题。一个很快,另一个很慢。

该表在Id列上有一个clusted索引。

-- Slow, uses clustered index scan reading 100100 rows
SELECT * 
FROM [dbo].[Foo] 
ORDER BY Id
OFFSET 100000 ROWS FETCH FIRST 100 ROWS ONLY

-- Fast, uses clustered index seek reading 100 rows
SELECT TOP 100 * 
FROM [dbo].[Foo]
WHERE Id > 100000
ORDER BY Id

计划是相同的,除了一个使用扫描另一个寻求。

任何人都可以解释为什么或这只是OFFSET的工作方式吗?

该表格很宽,有一些NVARCHAR(100-200)和一个NVARCHAR(2500)列。

1 个答案:

答案 0 :(得分:2)

这两个查询不相同。虽然可能会认为id没有间隙并从1开始,但数据库引擎并不知道。

组织索引以快速查找特定值。它们通常通过遍历树结构来实现这一点,并且通常是平衡的。您可以在documentation

中详细了解相关信息

但是,它们没有被组织起来以快速到达表中的 nth 行。因此,查询需要扫描表以计算行数。

也就是说,如果索引保持每个子节点中的行数,那么可以执行您想要的操作。请注意,这会使对表的修改变得复杂,因为需要为每个updateinsertdelete更新整个层次结构。