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

时间:2013-05-05 05:51:48

标签: sql-server sql-server-2008 sql-server-2005 sql-server-2012

我在SQL Server 2012提供的旧row_number(SQL Server 2008)和较新的OFFSET + FETCH(SQL Server 2012)分页机制的上下文中几乎没有问题。

  1. row_number()有什么限制?
  2. OFFSET + FETCH是row_number()的改进替代品吗?
  3. 是否有任何使用案例只能使用一个而不是另一个?
  4. 两者之间是否有任何性能差异?如果是,建议使用哪一个?
  5. 感谢。

3 个答案:

答案 0 :(得分:18)

使用ROW_NUMBER()可以正常工作 - 这只是必要的工作量;您需要围绕实际查询编写“骨架”CTE,将ROW_NUMBER()列添加到输出集,然后对其进行过滤。

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

总的来说:如果你使用 SQL Server 2012 - 那么你应该肯定使用OFFSET/FETCH而不是ROW_NUMBER()进行分页

答案 1 :(得分:2)

根据定义,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

答案 2 :(得分:1)

根据这篇文章3,分页比较技术和图表结果对选择分页方法很有用

Sql Server 2012 Paging Methods

小记录数量的所有分页方法工作正常,但是当增加记录数量时间差异下注方法似乎直接