做行政报表、整理客户名单、导出销售数据时,经常遇到上万条记录——直接 SELECT * 一跑,页面卡半天,Excel还打不开。这时候,分页不是‘高级功能’,而是日常刚需。
为什么不能一次全查出来?
数据库查10万行,哪怕只返回ID和姓名两列,网络传输、内存加载、前端渲染全得扛着。办公室老张上次导出客户表,没加限制,结果SQL Server直接把本地电脑内存占到95%,Excel打开就报错。
不同数据库的分页写法,真不一样
别再死记‘limit 10,20’了——那只是MySQL的语法,换到SQL Server或Oracle就失效。
MySQL / PostgreSQL(新版):OFFSET + LIMIT 最直白
SELECT id, name, phone FROM customer ORDER BY id ASC LIMIT 20 OFFSET 40;意思是:跳过前40条,取接下来20条(即第3页,每页20条)。注意:ORDER BY 必须有,否则分页结果可能乱序。
SQL Server 2012+:用 OFFSET FETCH 更稳
SELECT id, name, phone FROM customer ORDER BY id ASC OFFSET 40 ROWS FETCH NEXT 20 ROWS ONLY;和MySQL逻辑一致,但语法更明确,也支持无OFFSET的首页写法(OFFSET 0 ROWS)。
Oracle 12c+:ROW_NUMBER() 或 FETCH FIRST
推荐用 FETCH(简洁):
SELECT id, name, phone FROM customer ORDER BY id ASC OFFSET 40 ROWS FETCH NEXT 20 ROWS ONLY;老版本Oracle(如11g)只能靠子查询套 ROW_NUMBER:
SELECT id, name, phone FROM (SELECT id, name, phone, ROW_NUMBER() OVER (ORDER BY id) rn FROM customer) WHERE rn BETWEEN 41 AND 60;小技巧:别让分页变慢王
加了OFFSET,查第1000页(OFFSET 19980)会越来越慢——数据库仍要扫描前19980行。实际办公中,建议:
• 用“游标分页”替代大偏移量(比如记录上一页最后的id,下一页WHERE id > 12345);
• 在ORDER BY字段上建索引(如对customer.id建聚集索引);
• 导出全量数据时,改用SSIS、Navicat导出工具,别硬扛SQL分页。
财务小李上周导月度订单,用错写法导致报表刷新等两分钟。后来改成带索引的OFFSET FETCH,3秒出第50页——分页不是炫技,是让手头活干得顺一点。