【问题标题】:SQL Server : OFFSET FETCH performs scan while TOP WHERE performs seek?SQL Server:OFFSET FETCH 执行扫描,而 TOP WHERE 执行查找?
【发布时间】:2017-06-04 02:23:03
【问题描述】:

我收到了以下两个查询。一个快一个慢。

该表在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) 列。

【问题讨论】:

  • 注意:这些查询不一样!
  • OFFSET 必须扫描以计算行数,ID>.. 不能。他们可能会给出不同的结果

标签: sql sql-server pagination


【解决方案1】:

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

索引的组织是为了快速找到特定的值。他们通常通过遍历树结构来做到这一点,并且通常是平衡的。您可以在documentation 中阅读更多相关信息。

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

也就是说,如果索引保持每个子项的行数,可以做你想做的事。请注意,这会使修改表变得复杂,因为需要为每个 updateinsertdelete 更新整个层次结构。

【讨论】:

  • 谢谢。好点子。我认为通过使用统计数据,它会知道大部分范围是连续的。但仔细想想,这两个查询做的事情完全不同,而且根本不等价。
猜你喜欢
  • 2018-11-03
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多