电脑帮手
柔彩主题三 · 更轻盈的阅读体验

SQL查询分页写法:MySQL、SQL Server、Oracle和PostgreSQL怎么写

发布时间:2026-04-20 11:31:18 阅读:4 次

装机时配好数据库环境,开发或维护系统常会遇到数据量一大就卡顿的问题。比如后台要查用户列表,上万条记录全查出来,页面加载慢、内存爆掉、浏览器直接罢工。这时候,分页不是可选项,是必选项。

为什么不能一次查完再前端分页?

有人图省事,在程序里用 SELECT * FROM user 把全部数据捞出来,再用代码切片(比如 Python 的 list[10:20])。这在几百条数据时还凑合,一旦表里有几十万用户,光是网络传输+内存加载就得几秒,数据库连接池还可能被占满。真正的分页,得让数据库自己只吐出当前页要的那十几条。

主流数据库的分页写法

MySQL 8.0+:用 OFFSET + LIMIT 最直接

查第3页,每页10条(即跳过前20条,取10条):

SELECT id, username, email FROM user ORDER BY id DESC LIMIT 10 OFFSET 20;

注意:ORDER BY 必须有,否则分页结果可能错乱;OFFSET 值 = (页码 - 1) × 每页条数。

MySQL 5.7 及更早:只能用 LIMIT m,n

上面的例子等价写法:

SELECT id, username, email FROM user ORDER BY id DESC LIMIT 20, 10;

意思是“从第20条开始,取10条”。但这个语法容易看反,建议统一用 OFFSET + LIMIT 更清晰。

SQL Server:用 OFFSET FETCH(2012+ 推荐)

同样查第3页,每页10条:

SELECT id, username, email FROM user ORDER BY id DESC OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

必须带 ORDER BY,FETCH NEXT 不支持变量,但配合参数化查询很稳。

Oracle:ROWNUM 旧法易翻车,推荐用 FETCH FIRST(12c+)

老写法(不推荐):

SELECT * FROM (SELECT ROWNUM rn, t.* FROM (SELECT id, username, email FROM user ORDER BY id DESC) t WHERE ROWNUM <= 30) WHERE rn > 20;

嵌套两层,性能差还难读。新写法清爽多了:

SELECT id, username, email FROM user ORDER BY id DESC OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

PostgreSQL:跟 MySQL 类似,也支持 OFFSET + LIMIT

SELECT id, username, email FROM user ORDER BY id DESC LIMIT 10 OFFSET 20;

而且 PostgreSQL 对大偏移量(比如 OFFSET 100000)做了优化,比 MySQL 的 LIMIT 100000,10 更靠谱些。

实战小提醒

分页时别只盯着语法——id 是主键且连续还好说,如果按 create_time 排序,又存在时间相同的情况,不同页可能漏数据或重复。稳妥做法是:ORDER BY create_time DESC, id DESC,把 id 当第二排序字段兜底。

另外,真遇到百万级数据分页,OFFSET 越大越慢(数据库要先扫前面所有行)。这时候可以考虑游标分页(用上一页最后一条的 id 当起点),不过那是进阶玩法了,基础装机阶段先掌握上面这些够用了。