您的当前位置:首页 >人工智能 >这真的不是八股!经典 MySQL 大数据量查询分页问题 正文
时间:2025-11-04 13:16:32 来源:网络整理编辑:人工智能
查询分页一般要最少要执行两条 SQL 语句:复制SELECT COUNT(*) FROM tablename WHERE columnName = xx1.
查询分页一般要最少要执行两条 SQL 语句:
复制SELECT COUNT(*) FROM tablename WHERE columnName = xx1. 复制SELECT * FROM tablename WHERE columnName = xx limit 0,不股1001.正常情况下没有问题,但是经典当数据量非常大的时候,首先 count(*) 会非常慢这是数据肯定的,其次分页越多,量查limit 的询分效率就会越低。
比如limit 200000,页问 10,这个等同于数据库要扫描出 200010 条数据,不股然后再丢弃前面的经典 200000 条数据,返回剩下 10 条数据给用户,数据这种取法很明显越往后速度越慢,量查妥妥的询分慢 SQL。
《高性能 MySQL》中对这个问题有过说明:
分页操作通常会使用 limit 加上偏移量的页问办法实现,同时再加上合适的不股 order by 子句。但这会出现一个常见问题:当偏移量非常大的经典时候,它会导致 MySQL 扫描大量不需要的数据行然后再抛弃掉。
我们创建两张表(部门表和员工表),并模拟插入 500w 条员工数据:

测试下分页查询员工的 SQL 执行速度,先来看偏移量比较小的情况:
复制SELECT a.empno,a.empname,a.job,b.depno,b.depname from emp a left join dep b on a.depno = b.depno order by a.id desc limit 100,25; 受影响的行: 0 时间: 0.001s1.2.3.4.5.6.7.8.9.再来看下偏移量非常大的情况:
复制SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname from emp a left join dep b on a.depno = b.depno order by a.id desc limit 4800000,25; 受影响的行: 0 时间: 12.275s1.2.3.4.5.6.7.8.9.可以很明显的云南idc服务商看出,偏移量很小的时候,查询速度还是非常快的,当偏移量上到百万量级,这个执行时间已经无法忍受了,一条查询语句跑十几秒这不直接给数据库干阻塞了?
偏移量之前的数据是没有价值的,所以我们可以先在聚集索引中根据偏移量找到开始位置的 id 值,再根据这个 id 值去非聚集索引上查询所需要的行数据,这样就避免了大量的无用的回表查询。
总结来说就是:利用子查询获取偏移 n 条的位置 id,基于这个位置再往后取
复制SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname from emp a left join dep b on a.depno = b.depno where a.id >= (select id from emp order by id limit 4800000,1) order by a.id limit 25; 受影响的行: 0 时间: 1.541s1.2.3.4.5.6.7.8.9.10.11.可以看见,执行效率有显著提升
这个应该是比较常见的解决手段了,就是记住上次查找结果的主键位置,从而避免使用偏移量。
比如存储了上次分页的最后一条数据 id 是免费源码下载 4800000,SQL 就可以直接跳过4800000,从 4800001 开始扫描表
复制SELECT a.id,a.empno,a.empname,a.job,a.sal,b.depno,b.depname from emp a left join dep b on a.depno = b.depno where a.id > 4800000 order by a.id limit 25; 受影响的行: 0 时间: 0.000s1.2.3.4.5.6.7.8.9.10.11.这个效率是最好的,无论怎么分页,耗时基本都是一致的,因为他执行完条件之后,都只扫描了 25 条数据。
但这种方案只适合顺序分页(比如 Feeds 流场景),这样才能记住前一个分页的最后 id。如果用户跳着分页,比如刚刚刷完第 25 页,马上跳到 35 页,使用这种方案的话,数据显示的其实是 26 页的数据,而不是 35 页的。
这种方案属于兜底策略:为 limit 和 offset 设置一个最大值,超过这个最大值,分页查询接口就直接返回空数据或者返回错误码。
从业务角度来说,可以认为超过这个最大值用户已经不是在分页了,亿华云而是在刷数据,如果确实是要找某条数据,那么正常理解应该是输入合适的条件来适当缩小范围,而不是一页一页地分页。
三星台式电脑装机教程(简单易懂的三星台式电脑装机教程,助你快速搭建个人工作站)2025-11-04 12:12
Linux运维基础之文件属性block2025-11-04 11:54
Redis主从复制与单哨兵模式详解2025-11-04 11:32
赋能企业级移动应用 CFCA FIDO+提升安全与体验2025-11-04 11:11
探索oppocoloros2.0(从界面设计到个性化定制,发现coloros2.0的无限魅力)2025-11-04 10:59
熵基科技:万傲瑞达×火星慧知,解锁“空间智能”的未来之门2025-11-04 10:49
nginx 虚拟主机介绍与配置!2025-11-04 10:47
Python那些不为人知的实用功能和特点!2025-11-04 10:45
2000到3000元之间最值得入手的手机推荐(性价比高,功能强大,体验流畅,千元机选购指南)2025-11-04 10:35
Linux学习之kubeadm 安装k8s 1.15版2025-11-04 10:35
小米Note搭载MIUI8,为你带来怎样的使用体验?(深度探析MIUI8在小米Note上的亮点与优势)2025-11-04 12:38
Redis多哨兵模式详解!Linux运维培训班2025-11-04 12:38
linux文件目录结构汇总!2025-11-04 12:36
ElasticSearch分布式架构搭建详解!2025-11-04 12:32
世界最佳杀毒软件是什么?(揭秘最强大的杀毒软件,保护你的计算机安全!)2025-11-04 11:54
Go语言开发的分布式系统有哪些项目?2025-11-04 11:41
kubernetes集群常用资源(一)!LinuxSRE工程师培训2025-11-04 11:20
Python网络爬虫之图片懒加载技术、selenium和PhantomJS2025-11-04 11:17
如何使用笔记本修复教程解决BOSS问题(笔记本修复教程、解决BOSS问题)2025-11-04 11:11
Jenkins 2.516.2 配置(.net9+gitea+自由风格)2025-11-04 10:34