数据库分页慢到崩溃?这3个坑90%程序员都踩过
刷个抖音视频滑一下就能看下一个,逛淘宝商品列表翻页跟翻书一样快——这种丝滑体验背后,全是数据库分页在默默打工。但别被表面骗了,分页这玩意儿看着简单,真干起来能把程序员逼疯。数据量小的时候一切安好,百万级数据一上,查询直接卡成PPT,用户骂娘,老板拍桌,你熬夜改代码改到怀疑人生。这破事儿为啥这么难搞?今天咱们掰开揉碎聊清楚。 分页的本质就是"只拿该看的,别的先憋着"。数据库里明明躺着100万条记录,用户眼前就10条,你非得全读出来再扔掉99万,这不纯属吃饱了撑的?MySQL的LIMIT OFFSET看起来人畜无害,offset越大越露馅——查到第100页,数据库照样要从头数1000条再扔掉,越往后越慢,跟老太太数钱似的。真正的性能杀手在这儿:排序、回表、深度分页,三兄弟联手搞崩你的系统。索引建得不对,查询直接退化成全表扫描;加了ORDER BY却没覆盖索引,数据库满硬盘乱窜找数据,硬盘灯狂闪,你心也跟着狂跳。
光懂原理不够,还得会看菜下饭。小数据量直接LIMIT搞定,简单粗暴;数据上了规模就得换玩法——"延迟关联"用覆盖索引先捞ID,再回表取数据,能减少90%的IO;游标分页用上一页的最大ID当起点,彻底告别OFFSET的累赘,翻第1页和第10000页一样快,抖音小红书全是这套路。要是搞数据分析报表,ES、ClickHouse这些专门玩聚合的引擎才是正主,别拿MySQL硬刚。我见过最离谱的代码,分页查询里塞了个COUNT(*)算总页数,每次翻页都全表统计一遍,服务器差点冒烟。
说到底,分页不是写SQL,是算成本账。用户真的需要跳到第5873页吗?无限滚动加载是不是更香?产品需求得拆清楚,技术方案才能跟得上。很多"性能优化"根本就是伪需求,把跳转页码改成只能上一页下一页,问题消失一大半。技术选型别偷懒,该上缓存上缓存,该分库分库,指望一条SQL走天下,早晚被数据量教做人。
你在分页上踩过哪些坑?是深度分页卡到死,还是COUNT(*)把服务器查崩过?评论区聊聊,点赞最高的送一份我整理的《分页优化 cheat sheet》!