SQL Server分页查询:TOP方式与ROW_NUMBER()的性能对比分析

苏见山
苏见山
发布时间:2026-10-13| 4人浏览过
原创

在 SQL Server 数据库开发中,处理数据分页通常有两种经典写法:旧版的 TOP 嵌套子查询和 SQL Server 2005 引入的 ROW_NUMBER() 窗口函数。本文将展示这两种方式的代码实现,并通过执行计划和数据耗时证明后者具有更优的性能表现。

结果与目标

在进行大表分页查询时,选择合适的语法结构直接影响数据库响应速度。经过对同等条件下两种分页策略的实测,结论如下:

  • 效率差异:使用 ROW_NUMBER() 的方式相比传统的 TOP 嵌套方式,查询开销更低(执行比例约为 28:72)。
  • 执行优化:TOP 方式通常需要两次聚集扫描(Clustered Scan),而 ROW_NUMBER() 能有效优化读取路径。

准备条件

为了准确对比两种分页方案的底层行为,我们需要在数据库环境中执行以下操作来收集证据:

  1. 开启统计信息:在连接会话中执行 SET STATISTICS TIME ON; 以获取详细的 CPU 和时间消耗。
  2. 启用图形化计划:在 SQL Server Management Studio (SSMS) 工具栏点击“包含实际执行计划”(快捷键 Ctrl+M)。
  3. 目标表数据:假设存在一张名为 CLine_CommonImage 的数据表,按主键 id 排序。

真实操作顺序

第1步:实施 TOP 嵌套分页法

原理说明:该方法通过排除掉前 N 页的所有 ID,取剩余记录的前 M 条。逻辑上直观但物理执行上往往导致重复扫描。

示例参数:每页 10 条,查询第 5 页(即跳过前 40 条)。

SELECT TOP 10 * -- 页大小
FROM [TCCLine].[dbo].[CLine_CommonImage]
WHERE id NOT IN (
    SELECT TOP 40 id -- 页大小*(当前页-1)
    FROM [TCCLine].[dbo].[CLine_CommonImage] 
    ORDER BY id
)
ORDER BY id;

该语句执行后的典型结果集示意:

第2步:实施 ROW_NUMBER() 分页法

原理说明:利用窗口函数为每一行生成递增的行号,外层过滤行号大于起始索引的记录,再结合 TOP 限制返回数量。这是 SQL Server 2005+ 推荐的标准做法。

通用模板:

SELECT TOP @pageSize * 
FROM (
    SELECT ROW_NUMBER() OVER(ORDER BY @orderColumn) AS rownumber, *
    FROM (@baseQuery) AS t
) AS o
WHERE rownumber > @startIndex;

对应上述示例的具体实现:

SELECT TOP 10 numComImg.*
FROM (
    SELECT ROW_NUMBER() OVER(ORDER BY id ASC) AS rownumber, *
    FROM (
        SELECT * FROM [TCCLine].[dbo].[CLine_CommonImage]
    ) AS comImg
) AS numComImg
WHERE rownumber > 40;

该语句执行后的结果集示意:

第3步:对比执行计划开销

将两段 SQL 连同统计开关放在一起运行,观察 SSMS 生成的执行计划。可以清晰看到两者的操作符权重分配差异:

-- 开启统计时间
SET STATISTICS TIME ON;
GO

-- 1. ROW_NUMBER 方式
SELECT TOP 10 ... WHERE rownumber > 40;

-- 2. TOP 嵌套方式
SELECT TOP 10 ... WHERE id NOT IN (SELECT TOP 40 ...);

在执行计划视图中,左侧柱状图显示 ROW_NUMBER() 方式仅占用约 28% 的预估开销,而右侧传统的 TOP 方式占据了 72%。这是因为 TOP 嵌套方案在 `NOT IN` 子查询和主查询中分别触发了全表或索引的聚集扫描,增加了 I/O 负载。

完成判断与时耗验证

除了执行计划的视觉对比,`SET STATISTICS TIME ON` 输出的文本日志提供了精确的时间指标,进一步佐证了性能差距。

ROW_NUMBER() 方式耗时情况:

TOP 嵌套方式耗时情况:

从日志数据可以看出,尽管两者返回相同的数据结果,但 ROW_NUMBER() 解析函数在处理大数据集时分摊了计算压力,避免了冗余的二次排序或扫描操作。因此在绝大多数生产环境场景下,建议优先采用基于 ROW_NUMBER() 的分页策略。

简要总结

以上关于 SQL Server 分页查询 TOP 方式与 ROW_NUMBER() 解析函数的不同点及性能表现的详细内容,更多关于数据库优化的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。