mssql分页到底怎么样,性能好不好,优势在哪儿说说看
- 问答
- 2026-01-03 21:58:32
- 11
关于MSSQL(也就是Microsoft SQL Server)的分页功能到底怎么样,性能好不好,优势在哪儿,这是一个非常实际的问题,我们不能一概而论地说它好或不好,因为这完全取决于你“怎么用”,MSSQL提供了现代且高效的官方分页方法,只要使用得当,性能是非常出色的,但如果用了过时或错误的方法,性能可能会非常糟糕。
MSSQL分页的“王者”:OFFSET FETCH子句
这是目前MSSQL官方推荐、也是最主流的分页方式,从SQL Server 2012版本开始引入,它的写法非常直观,就像它的名字一样。
怎么用?
基本语法是这样的:ORDER BY SomeColumn OFFSET {跳过的行数} ROWS FETCH NEXT {要取的行数} ROWS ONLY。
举个例子,假设你有一个商品表,有10万条数据,你想实现像电商网站那样“下一页”的效果,每页显示20条。
- 第一页:
ORDER BY ProductID OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY,意思是,按ProductID排序,跳过0行,取接下来的20行。 - 第二页:
ORDER BY ProductID OFFSET 20 ROWS FETCH NEXT 20 ROWS ONLY,跳过20行,再取20行。 - 以此类推。
优势在哪儿?

- 语法简单明了: 这是它最大的优点之一,一看就懂,几乎不需要额外解释,降低了开发和维护的心智负担,相比于过去复杂的分页方法,这简直是一种解放。
- 官方标准支持: 它是ANSI SQL标准的一部分,这意味着你的分页查询在不同数据库系统间的可移植性更好(不同数据库实现细节可能有差异)。
- 性能在大多数情况下良好: 对于中小型数据量,以及翻页深度不深(比如前100页)的场景,
OFFSET FETCH的性能是完全可接受的,数据库引擎会智能地利用排序索引来高效地跳过指定行数。
性能陷阱要注意:
OFFSET FETCH有一个著名的“阿喀琉斯之踵”:越往后翻页,性能越差,为什么?因为OFFSET 100000 ROWS并不是直接“跳”到第10万行,而是需要先排序并扫描前面的10万行,然后把它们“扔掉”,再取后面的20行,当你翻到几千页之后,这个“跳过”的成本会变得非常高,微软官方文档和众多数据库专家(如Brent Ozar等)都指出过这个问题,它适合“深度”不大的分页。
曾经的“主流”与现在的“陷阱”:ROW_NUMBER()函数
在OFFSET FETCH出现之前,MSSQL中最常用的分页方法是使用ROW_NUMBER()窗口函数,它的思路是:先给查询结果集生成一个连续的行号,然后根据这个行号来筛选。
怎么用?
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY ProductID) as RowNum FROM Products ) AS T WHERE RowNum BETWEEN 21 AND 40; -- 这就是第二页

现在来看它的地位:
这种方法在SQL Server 2005时代是“救世主”,比更古老的TOP N方法好得多,但自从有了OFFSET FETCH,它就显得有些“过时”和“臃肿”了,它的性能特点和OFFSET FETCH类似,也存在深度分页性能下降的问题,而且语法更复杂,除非你需要对分页逻辑做非常复杂的定制(比如不连续的页码计算),否则不建议再将其作为首选。
应对海量数据分页的“杀手锏”:Keyset Pagination(键集分页)
当你的数据量极大(数百万甚至上亿),并且用户真的需要翻到很深的页面时,无论是OFFSET FETCH还是ROW_NUMBER()都会力不从心,这时,就需要用到一种更高级的策略,常被称为“键集分页”或“搜索法分页”。
核心思想: 它完全摒弃了“跳过N行”的思路,而是记住“上一页最后一条记录的位置”,然后直接从这个位置开始往后找。

怎么用? 假设我们还是按ProductID排序。
- 第一页:
SELECT TOP 20 * FROM Products ORDER BY ProductID ASC;,应用程序要记住这一页最后一条记录的ProductID(比如是100)。 - 第二页:
SELECT TOP 20 * FROM Products WHERE ProductID > 100 ORDER BY ProductID ASC;,你看,这里没有OFFSET,而是直接查询ID大于100的20条记录,同时再记住本页最后一条记录的ID(比如是120)。 - 第三页:
SELECT TOP 20 * FROM Products WHERE ProductID > 120 ORDER BY ProductID ASC;。
优势在哪儿?
- 极致性能,恒定速度: 这是它最逆天的优势,无论你翻到第1页还是第10000页,查询速度都几乎一样快!因为它利用了索引(通常是主键或唯一索引)进行范围查询,数据库可以直接定位到数据开始的位置,然后连续读取20行就行,效率极高,数据库专家如Tibor Karaszi在其文章中也极力推荐这种分页方式用于高性能场景。
- 避免丢失数据: 在传统分页过程中,如果源数据有新增或删除,页码可能会“漂移”,而键集分页基于稳定的排序键,受数据变动的影响较小。
劣势在哪儿?
- 无法直接跳页: 用户不能直接从第1页跳到第100页,因为要查询第100页,你需要知道第99页最后一条记录的ID是什么,所以它通常用于“上一页/下一页”这种连续翻页的场景。
- 实现稍复杂: 应用程序需要维护这个“最后一条记录的位置”。
- 常规应用,翻页不深(如后台管理系统、前几百页的列表): 大胆使用
OFFSET FETCH,它简单、够用,是平衡了易用性和性能的最佳选择。 - 海量数据,深度翻页(如社交媒体的时间线、日志查询): 必须考虑 键集分页(Keyset Pagination),虽然牺牲了直接跳页的灵活性,但换来了毫秒级的恒定响应时间,体验极佳。
- ROW_NUMBER()方法: 了解即可,在新项目中不建议主动使用。
MSSQL的分页性能好不好?答案是:工具本身很强大,提供了从易用到高效的多种选择,关键在于作为开发者的你,能否根据业务场景选择最合适的那一把“利器”。
本文由盘雅霜于2026-01-03发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/73945.html