在 SQL Server 2012 提供的较旧的 row_number (SQL Server 2008) 和较新的 OFFSET + FETCH (SQL Server 2012) 分页机制的上下文中,我有几个问题。
- row_number() 有什么限制?
- OFFSET + FETCH 是 row_number() 的改进替代品吗?
- 是否有任何用例只能使用一个而不是另一个就足够了?
- 两者之间有性能差异吗?如果是,推荐哪一种?
谢谢。
在 SQL Server 2012 提供的较旧的 row_number (SQL Server 2008) 和较新的 OFFSET + FETCH (SQL Server 2012) 分页机制的上下文中,我有几个问题。
谢谢。
使用ROW_NUMBER()
效果很好 - 这只是比必要的工作更多;您需要围绕您的实际查询编写一个“骨架”CTE,将该ROW_NUMBER()
列添加到您的输出集中,然后对其进行过滤。
使用新OFFSET / FETCH
的更简单 - 是的,它对性能也更好,因为这两个链接可以告诉你:
总的来说:如果您使用的是SQL Server 2012 - 那么您绝对应该使用OFFSET/FETCH
而不是ROW_NUMBER()
用于分页
根据定义ROW_NUMBER
,是运行查询时计算的临时值。OFFSET / FETCH
是您可以为ORDER BY
子句指定的选项。
在速度方面,它们都实现了出色的性能,并且每种方法之间的差异取决于您在SELECT
子句中指定的列和您在表上拥有的索引。
在以下 2 个示例中,您可以看到两种方法之间的区别:
1. OFFSET / FETCH 比较快的情况:
SELECT
Id
FROM Orders
ORDER BY
Id
OFFSET 50000 ROWS FETCH NEXT 5000 ROWS ONLY
SELECT
A.Id
FROM
(
SELECT
Id,
ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber FROM Orders
) AS A
WHERE
A.RowNumber BETWEEN 50001 AND 55000
2. ROW_NUMBER() 更快的情况:
SELECT
*
FROM Orders
ORDER BY
Id
OFFSET 50000 ROWS FETCH NEXT 5000 ROWS ONLY
SELECT
A.*
FROM
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber FROM Orders
) AS A
WHERE
A.RowNumber BETWEEN 50001 AND 55000
I found this article which presents 3 techniques of paging compares their results in a chart. Might be helpful in deciding which approach you want to follow.
Paging Function Performance in SQL Server 2012
All of the paging methods discussed work fine for smaller amounts of records, but not so much for larger quantities of data.