SQL分页查询实现方法_SQL LIMIT分页示例说明

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 性能陷阱。