前置说明:下面对比以 MySQL 为主(InnoDB),同时补充 PostgreSQL、SQL Server 的差异;核心痛点不是 LIMIT,而是大偏移量
OFFSET N。 测试前提:主键自增、有合适索引、单表,无复杂 join,数据量 10w~1000w。
一、主流分页方式汇总
LIMIT offset, size(传统偏移分页)
SELECT * FROM t ORDER BY id LIMIT 10000, 20;
主键书签分页(keyset / 游标分页,推荐)
SELECT * FROM t WHERE id > 10000 ORDER BY id LIMIT 20;
子查询先定位偏移(延迟关联)
SELECT a.* FROM t a
INNER JOIN (SELECT id FROM t ORDER BY id LIMIT 10000,20) b
ON a.id = b.id;
ROW_NUMBER () 窗口函数分页
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER(ORDER BY id) AS rn FROM t
) tmp WHERE rn BETWEEN 10001 AND 10020;
SQL Server OFFSET ... FETCH
SELECT * FROM t ORDER BY id OFFSET 10000 ROWS FETCH NEXT 20 ROWS ONLY;
PostgreSQL LIMIT/OFFSET 和 MySQL 行为接近,另外支持
FETCH
二、性能对比表
关键原理(MySQL InnoDB)
LIMIT 10000,20:
按索引有序扫描 10020 行
扔掉前面 10000 行,返回后面 20 行 👉 offset 越大,丢弃的数据越多,时间线性上涨。
书签分页 where id>xxx limit 20:
索引直接定位
id>xxx的位置只读取需要的 20 行 👉 无论第几页,扫描行数固定,性能稳定。
三、扩展:多字段排序下的书签分页
很多场景不是按 id,而是 order by create_time, id(防止时间重复顺序错乱)
-- 上一页最后一条:create_time='2026-10-01 12:00:00', id=12345
SELECT * FROM t
WHERE create_time < '2026-10-01 12:00:00'
OR (create_time = '2026-10-01 12:00:00' AND id < 12345)
ORDER BY create_time DESC, id DESC
LIMIT 20;
联合索引:(create_time desc, id desc),否则性能暴跌。
限制:不能跳页;前端只能记住上一页最后一条的排序字段值,不能输入页码。
四、各个数据库特殊点
PostgreSQL
OFFSET和 MySQL 一样,深分页慢;同样优先 keyset;
支持
FETCH NEXT n ROWS ONLY,语法糖,底层和 LIMIT 无本质区别;大结果集排序会耗 shared buffer。
SQL Server
OFFSET ... FETCH就是官方分页,本质也是偏移分页,深分页一样慢;窗口函数
ROW_NUMBER()经常被业务用来分页,但千万不要深偏移;书签方案同样最优。
Oracle
老版本:
ROWNUM嵌套分页,经典两层子查询,深分页开销巨大;12c+:
OFFSET ... FETCH,同样偏移分页;最优依然是 keyset。
五、常见误区
❌ “加了索引 LIMIT 大偏移就很快” 索引只是让排序快,offset 丢弃行的开销依然存在。
❌ “ROW_NUMBER 比 LIMIT 性能更好” 小页码差别不大,深偏移下更慢,因为要计算、存储行号。
❌ “延迟关联可以无限深分页” 只是优化了回表,扫描 offset 行的成本还在,offset 几十万照样慢。
❌ 用 count (*) 算总条数 + 页码
count(*)全表扫描,千万级表非常慢;信息流不要返回 total,后台管理可以缓存总数或者近似值(MySQL information_schema、PG 估算)。
六、选型建议
C 端 APP、信息流、下拉滚动(无跳页需求) → 书签分页(keyset) ✅ 首选,性能最稳
后台管理系统,必须支持输入页码、跳转到任意页
页码小:直接 LIMIT offset,size
页码很大:不支持,或者限制最大页码;用延迟关联做优化
复杂报表、多表 join、多字段无序排序
优先提前预聚合到数仓(ClickHouse / Doris),不要在 OLTP 库分页
千万级以上数据:尽量放弃 “随机页码分页” 的产品设计
本文原创作者:易君召,详见:https://www.yijunzhao.cn/authors/yijunzhao,转载请注明出处。
原文链接
欢迎访问 小易撩挨踢