SQL分页查询最常用方式是LIMIT+OFFSET(MySQL/PostgreSQL)、OFFSET-FETCH(SQL Server 2012+)、ROW_NUMBER()或FETCH(Oracle),深分页应改用主键范围过滤以提升性能。

SQL分页查询最常用、最直接的方式就是用 LIMIT(MySQL/PostgreSQL)或 TOP + OFFSET(SQL Server)等语法实现。核心思路是:跳过前 N 条记录,再取 M 条。下面以主流数据库为例说明实用写法。
MySQL / PostgreSQL:LIMIT + OFFSET 最简分页
这是最直观的写法,适合中小数据量场景:
-
语法格式:
LIMIT 每页条数 OFFSET 跳过的条数 -
第2页,每页10条(即跳过前10条,取第11–20条):
SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 10; - 注意:OFFSET 值 = (页码 − 1) × 每页条数;页码从1开始计数
- 性能提示:OFFSET 越大,扫描行数越多,深分页(如第10000页)会明显变慢
优化深分页:用主键/索引列替代 OFFSET
当页码很大时,用 WHERE + 主键范围过滤比 OFFSET 更高效:
-
前提:表有自增主键(如
id)且已按该字段排序 -
第2页(每页10条)可改写为:
SELECT * FROM users WHERE id > 10 ORDER BY id LIMIT 10; -
第1000页(每页10条):先查出第999页最后一条的
id(比如是 9990),再执行:SELECT * FROM users WHERE id > 9990 ORDER BY id LIMIT 10; - 优势:避免全表扫描跳过大量记录,依赖索引快速定位
SQL Server:使用 OFFSET-FETCH(SQL Server 2012+)
标准 ANSI SQL 支持方式,语义清晰:
-
语法:
ORDER BY ... OFFSET N ROWS FETCH NEXT M ROWS ONLY -
第3页,每页20条:
SELECT * FROM orders ORDER BY order_date DESC OFFSET 40 ROWS FETCH NEXT 20 ROWS ONLY; -
注意:必须带
ORDER BY,否则报错;OFFSET 同样存在深分页性能问题
Oracle:ROWNUM 与 ROW_NUMBER() 的区别用法
老版本用 ROWNUM(伪列),但需嵌套子查询;新写法推荐窗口函数:
-
ROW_NUMBER() 示例(推荐):
SELECT * FROM (SELECT t.*, ROW_NUMBER() OVER (ORDER BY id) rn FROM users t) WHERE rn BETWEEN 21 AND 30;(第3页,每页10条) -
ROWNUM 注意:它在结果生成时就赋值,不能直接写
WHERE ROWNUM BETWEEN 21 AND 30,必须先给 ROW_NUMBER 再过滤 -
Oracle 12c+ 支持 FETCH:类似 SQL Server,
ORDER BY id FETCH FIRST 10 ROWS ONLY OFFSET 20 ROWS
基本上就这些。选哪种方式,主要看数据库类型和数据规模。小项目用 LIMIT OFFSET 足够;高并发或大数据量系统,建议结合主键/时间戳做游标分页,避免 OFFSET 性能陷阱。










