列表翻到第 50 页就卡:深分页为什么慢,延迟关联 + 游标分页实测对比
职位列表分页前 20 页嗖嗖的翻到 50 页以后明显卡顿接口从 90ms 涨到 900ms。同样的 SQLLIMIT 0, 20和LIMIT 980, 20差距能到十倍。以前觉得不就是 limit 吗直到线上被打脸才认真把深分页的账算明白。这篇用实测数据说话。先看慢在哪LIMIT 大偏移的真实开销表还是那张 300 万行的job_post列表查询长这样SELECTid,company_id,salary_min,post_timeFROMjob_postWHEREcity_code440300ANDstatus1ORDERBYpost_timeDESCLIMIT980,20;执行计划看着还行——有索引、没全表扫。但LIMIT 980, 20的实际动作是InnoDB 先把前 980 行全部扫描出来丢掉再返回最后 20 行。偏移越大白白扫描和丢弃的行越多行数是指数级上涨的LIMIT 0, 20 → 扫描 20 行 LIMIT 980, 20 → 扫描 1000 行 LIMIT 99980, 20 → 扫描 100000 行更狠的是排序。ORDER BY post_time DESC如果没吃到索引MySQL 要把符合条件的所有行都放进 filesort 排序排完再切分页——数据量大起来filesort 直接吃掉几秒。深分页慢的本质不是查 20 行慢是排序 扫描丢弃前 N 行慢。方案一延迟关联先取 id 再回表思路先只查主键跳过回表等把该返回的 20 个 id 定下来再 join 回原表取完整字段。分页子查询里的扫描依然存在但扫描的是覆盖索引只读 id 和排序列不碰行数据省掉大量回表 IOSELECTt.id,t.company_id,t.salary_min,t.post_timeFROMjob_post tINNERJOIN(SELECTidFROMjob_postWHEREcity_code440300ANDstatus1ORDERBYpost_timeDESCLIMIT980,20)tmpONt.idtmp.idORDERBYt.post_timeDESC;实测同样LIMIT 980, 20延迟关联把耗时从 900ms 压到 210ms 左右。代价是写法丑MyBatis-Plus 里要写自定义 SQLPageHelper 帮不了你。适合偏移不是特别大但回表量明显的场景是性价比最高的第一步。方案二游标分页把偏移换成起点列表是按时间倒序往下翻的话可以不用页码改用上次最后一条的位置继续翻。MySQL 里最朴素的实现就是带 WHERE 的 LIMIT-- 第一页SELECTid,company_id,salary_min,post_timeFROMjob_postWHEREcity_code440300ANDstatus1ORDERBYpost_timeDESCLIMIT20;-- 下一页传上次最后一条的 post_time 和 idSELECTid,company_id,salary_min,post_timeFROMjob_postWHEREcity_code440300ANDstatus1AND(post_time2026-10-08 12:00:00OR(post_time2026-10-08 12:00:00ANDid102456))ORDERBYpost_timeDESCLIMIT20;关键在post_time相同的情况——时间可能重复所以必须加 id 做第二排序键否则同一秒发布的职位会翻页丢失或重复。游标分页不管翻多少页扫描量恒等于本页该读的行100 页和 1 页耗时基本一样这才是根治。踩坑记录游标分页把倒序翻成了正序现象游标分页上线后用户反馈列表越翻越乱翻几页后出现重复数据而且新发布的职位不出现。排查过程先查接口入参前端传的 lastPostTime 和 lastId 都正常。再看 SQL发现问题在排序方向——列表要post_time DESC新的在前游标条件写的却是post_time lastPostTime继续找更新的倒序列表配正序游标永远找不全。定位思路游标条件和排序方向必须配套。DESC排序要往下翻游标条件是比上一条更小或相等且 id 更小写成更大就整个反了。代码里两个地方不一致——接口层排序写 DESCSQL 拼接游标条件时复制错了模板方向没跟着改。最终解决游标条件生成收敛成一个方法方向参数化杜绝手拼// direction -1 表示倒序新的在前游标取更小值publicstaticStringbuildCursorCondition(intdirection,StringtimeCol,StringidCol,ObjectlastTime,ObjectlastId){if(lastTimenull){return;// 第一页无游标}if(direction0){return(timeCol ? OR (timeCol ? AND idCol ?));}return(timeCol ? OR (timeCol ? AND idCol ?));}方案三别翻那么深——产品侧限深说到最后还有个大实话业务上没几个用户真会翻到第 100 页。列表 搜索场景产品侧把翻页上限卡在 50 页超出提示条件太窄换个筛选配合搜索条件本身就能过滤大部分深分页流量。技术方案做得再好也不如产品上不让它发生。可直接复用的清单深分页慢的本质排序 扫描丢弃前 N 行不是查 20 行慢。中浅偏移先上延迟关联子查询先取 id 再回表改动小见效快。无限滚动列表直接游标分页排序键 唯一键双条件扫描量恒定。游标方向必须和排序方向配套DESC 配小于ASC 配大于条件生成统一收口。时间戳可能重复游标必带 id 第二排序键否则翻页丢数据。产品侧限深分页上限 50 页技术 产品双管齐下。

相关新闻

接口幂等别再只靠前端防抖:@Idempotent 注解 + Redis 锁 + 请求指纹,重复提交直接拦

接口幂等别再只靠前端防抖:@Idempotent 注解 + Redis 锁 + 请求指纹,重复提交直接拦

下单、提现、结算这种接口,前端防抖只能挡住"手快双击",挡不住网络重试、客户端重复请求、后端超时重发。最典型的翻车现场:用户提现点了两次,钱包扣了两笔,客服电话直接被打爆。qkl-boot 里用 Idempotent 注…

2026/10/10 4:44:19 阅读更多 →
硕词 AI PPT 自动生成 —— 开题答辩、毕业答辩一键完成

硕词 AI PPT 自动生成 —— 开题答辩、毕业答辩一键完成

论文写完后,答辩 PPT 制作又成为新的压力。硕词 AI 支持 AI PPT 自动生成,访问 www.shuociai.com,可根据论文内容一键生成完整答辩 PPT。 PPT 内容包括研究背景、意义、方法、框架、结论、创新点、展望等完整结构,页面简洁大方&am…

2026/10/10 4:44:19 阅读更多 →
Spirent TestCenter 实战:从零跑通 RFC 2544 吞吐量测试

Spirent TestCenter 实战:从零跑通 RFC 2544 吞吐量测试

简介:《Spirent TestCenter简易操作手册》以PPT形式呈现,是一份面向网络测试工程师、设备调试人员及网络运维者的实用入门资料,旨在帮助零基础或初级使用者快速上手思博伦TestCenter网络测试仪表,掌握网络流量配置与管理方法。内容…

2026/10/10 4:43:19 阅读更多 →

最新新闻

AnyPS5项目解析:跨平台PS5兼容层技术原理与应用

AnyPS5项目解析:跨平台PS5兼容层技术原理与应用

我无法基于当前输入生成符合要求的博文。原因如下:输入中仅提供了项目标题"AnyPS5",但未提供任何实质性的【项目正文】、【关键词】或【摘要描述】;所谓“相关热搜词”和“最新网络热词”字段为空,无实际内容可供分析&a…

2026/10/10 5:19:31 阅读更多 →
机器学习预测股票:目标设计、特征工程与时间序列验证指南

机器学习预测股票:目标设计、特征工程与时间序列验证指南

简介:这份论文以股票预测为研究对象,系统梳理了仅使用历史数据与结合金融新闻文本的两类预测方法,涵盖分段线性表示、高斯过程分类、随机森林、深度递归神经网络、CNN、LSTM以及双重注意力机制等核心技术,并进一步介绍新闻事件结构…

2026/10/10 5:19:31 阅读更多 →
Python+Netmiko网络设备自动化配置实战:从批量备份到VLAN下发

Python+Netmiko网络设备自动化配置实战:从批量备份到VLAN下发

一直手动敲命令做网络配置的朋友,应该都体会过那种感觉:几十台交换机,一台台登录、一条条敲VLAN、改接口、配路由,碰上割接窗口更是连水都顾不上喝。我真正下决心用Python做网络设备自动配置,是在一次凌晨两点的批量变…

2026/10/10 5:19:31 阅读更多 →
个人置顶帖与投稿汇总:把内容资产变成可复利的方法论

个人置顶帖与投稿汇总:把内容资产变成可复利的方法论

这篇置顶帖和投稿汇总的做法,算是我折腾了大半年内容运营之后,最想分享给同行的一批实操沉淀。起因其实特别普通:有段时间我同时维护着两三个内容账号,又在不同平台投过几篇稿子,时间一长,我连自己写过哪些…

2026/10/10 5:19:31 阅读更多 →
在 React NodeGui 中使用原生 Node 模块:Qode 重编译与 node-pre-gyp 兼容性实战

在 React NodeGui 中使用原生 Node 模块:Qode 重编译与 node-pre-gyp 兼容性实战

桌面应用跨平台 【免费下载链接】react-nodegui Build performant, native and cross-platform desktop applications with native React powerful CSS like styling.🚀 项目地址: https://gitcode.com/gh_mirrors/re/react-nodegui 点击查看 免费下载 …

2026/10/10 5:19:31 阅读更多 →
Leaflet Map Panes 完全指南:用自定义图层层级(Custom Pane)控制图层叠加顺序

Leaflet Map Panes 完全指南:用自定义图层层级(Custom Pane)控制图层叠加顺序

前端数据可视化GIS 【免费下载链接】Leaflet 🍃 JavaScript library for mobile-friendly interactive maps 🇺🇦 项目地址: https://gitcode.com/gh_mirrors/le/Leaflet 点击查看 免费下载 导读 Map Panes(地图窗格…

2026/10/10 5:18:31 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →