在SQL Server中,旧的row_number()和新的基于OFFSET + FETCH的分页有什么区别?



我在SQL Server 2012提供的旧row_number (SQL Server 2008)和新OFFSET + FETCH (SQL Server 2012)分页机制的背景下有几个问题。

  1. row_number()有什么限制?
  2. OFFSET + FETCH是row_number()的改进替代品吗?
  3. 是否存在只使用其中一种而不使用另一种的用例?
  4. 两者的性能有什么不同吗?如果是,推荐使用哪一种?

谢谢。

使用ROW_NUMBER()工作得很好-它只是比必要的工作更多;您需要围绕您的实际查询编写一个"骨架"CTE,将ROW_NUMBER()列添加到您的输出集,然后对其进行过滤。

使用新的OFFSET / FETCH更简单-是的,它也更好的性能,因为这两个链接可以告诉你:

  • SQL Server 2012的新功能
  • 比较不同SQL Server分页的性能
所以总的来说:如果你是使用 SQL Server 2012 -那么你应该绝对使用OFFSET/FETCH而不是ROW_NUMBER()分页

根据定义,ROW_NUMBER是在运行查询时计算的临时值。OFFSET / FETCH是一个选项,您可以为ORDER BY子句指定。

在速度方面,它们都实现了很好的性能,每种方法之间的差异取决于您在SELECT子句中指定的列和您在表上的索引。

在下面两个示例中,您可以看到两个方法之间的区别:

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

我找到了这篇介绍3种分页技术的文章,并用图表比较了它们的结果。可能有助于决定您要采用哪种方法。

SQL Server 2012的分页功能性能

讨论的所有分页方法都可以很好地处理少量的记录,但对于大量的数据就不那么好了。

最新更新