当前位置: 代码网 > it编程>数据库>Mysql > MySQL中深度分页问题的解决方案

MySQL中深度分页问题的解决方案

2026年08月28日 Mysql 我要评论
问题现象:select * from table limit 100000,10跳过10万行再取10条。mysql需要扫描并丢弃前面100000条数据,偏移量越大,性能越差。方案1:主键索引优化(最常

问题现象:select * from table limit 100000,10
跳过10万行再取10条。mysql需要扫描并丢弃前面100000条数据,偏移量越大,性能越差。

方案1:主键索引优化(最常用,推荐)

利用主键有序,避免大offset跳过数据

-- 低效深度分页
select * from user limit 100000,10;

-- 优化:记住上一页最大id,where条件过滤
select * from user where id > 100000 limit 10;

✅优点:走主键索引,速度很快
❌缺点:

  1. 不适合id有删除、断号;
  2. 不能支持跳页(只能上一页、下一页,类似app滚动翻页),不能直接跳到第1000页。

方案2:子查询延迟关联

先通过索引拿到主键,再回表查询完整数据,减少回表开销

select u.* from user u 
inner join (select id from user limit 100000,10) t 
on u.id = t.id;

原理:子查询只扫描索引,不需要读取整行,拿到id之后再关联查完整记录。
适合业务需要支持跳页,又不能用id>xxx的场景。

方案3:覆盖索引

如果查询字段全部在索引里,不需要回表,深度分页压力会小很多。

-- name,phone建立联合索引
select id,name,phone from user limit 100000,10;

方案4:业务层面限制(互联网优先)

  1. 禁止前端直接跳转到几万页,只提供上一页、下一页;
  2. 大数据列表,不使用offset分页,使用游标分页(传最后一条id/时间戳)
  3. 导出大量数据不要用limit分页,使用流式读取。

方案5:使用时间戳做游标(非自增主键场景)

如果没有连续自增id,可以用创建时间作为游标

select * from user where create_time < '2026‑08‑20 12:00:00' order by create_time desc limit 10;

注意:排序字段必须建立索引。

不推荐的做法

  1. limit offset,size offset很大,性能暴跌;
  2. select count(*) from table 统计总条数,大表count很慢,前端不要展示总页数。

补充:为什么limit offset,size慢?

innodb执行limit 100000,10,会从索引读取100010行,前100000行全部丢弃,只返回后10条。offset越大,扫描行数越多。

面试小结

  • 如果是app滚动下拉:优先游标分页(id>上一页最大id),性能最好;
  • 如果必须支持跳页:用延迟关联子查询
  • 大表尽量避免给前端展示总条数,放弃跳页功能;
  • 排序字段务必建立索引,否则深度分页会更慢。

总结:
深度分页根源是大offset会扫描大量无效数据;优先游标分页记住上一页最后一条主键;需要跳页就用延迟关联;业务层面尽量不支持跳转到很深页码;大表避免count统计总数量。

以上就是mysql中深度分页问题的解决方案的详细内容,更多关于mysql深度分页问题的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com