SQL Server:OFFSET FETCH执行扫描,而TOP执行查找?

SQL Server:OFFSET FETCH执行扫描,而TOP执行查找?,sql,sql-server,pagination,Sql,Sql Server,Pagination,我得到以下两个问题。一个快,另一个慢 该表在Id列上有一个聚集索引 -- 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

我得到以下两个问题。一个快,另一个慢

该表在
Id
列上有一个聚集索引

-- 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)
列。

这两个查询并不相等。尽管您可能会假设
id
s没有间隙并且从1开始,但数据库引擎并不知道这一点

-- 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
索引被组织起来以快速查找特定的值。它们通常通过遍历一个树结构来实现这一点,而树结构通常是平衡的。有关这方面的更多信息,请参阅

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


也就是说,如果索引保持每个子级中的行数,那么它可以做您想要做的事情。请务必意识到,这将使表的修改复杂化,因为每次
更新
插入
删除
都需要更新整个层次结构。注意:这些查询是不同的!偏移量必须扫描以计数行,ID>。。不能。A他们可能会给出不同的结果谢谢。说得好。我认为,通过使用统计数据,它会知道大部分范围是连续的。但考虑到这一点,很明显,这两个查询做的事情完全不同,根本不等同。