当前位置: 首页 > article >正文

MyBatis RowBounds分页踩坑实录:一次线上OOM事故教会我的事

MyBatis分页陷阱从RowBounds内存泄漏到高效分页实战凌晨三点手机突然响起刺耳的报警声。打开监控系统一看某核心服务的堆内存曲线像坐了火箭一样直线上升最终触发了OOM崩溃。经过彻夜排查罪魁祸首竟是项目中一段看似无害的MyBatis分页代码——new RowBounds(0, 10)。这次事故让我深刻认识到在数据量爆炸的时代分页查询远不是简单的limit参数就能解决的问题。1. 线上OOM事故现场还原那是一个普通的业务迭代日我们上线了一个新的用户列表查询功能。初期测试时一切正常直到三个月后的某个营销活动日系统突然崩溃。查看错误日志时发现了这样的关键信息java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124) at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:354)事故特征分析发生时间业务高峰期上午10:00-11:00影响范围所有依赖用户列表查询的接口数据规模用户表记录数从上线时的1万条增长到120万条关键代码片段public ListUser getUsers(RowBounds rowBounds) { return userMapper.selectAllUsers(rowBounds); }注意这种先全量查询再内存分页的模式在数据量超过10万条时就可能成为定时炸弹2. RowBounds工作原理深度解析打开MyBatis源码在DefaultResultSetHandler类中找到了问题的根源。RowBounds实现的是典型的逻辑分页机制// 简化后的核心逻辑 private void handleRowValues(ResultSet rs, RowBounds rowBounds) throws SQLException { skipRows(rs, rowBounds.getOffset()); // 先跳过offset条记录 int count 0; while (count rowBounds.getLimit() rs.next()) { // 处理单行数据 count; } }物理分页 vs 逻辑分页对比特性物理分页逻辑分页(RowBounds)执行位置数据库层面应用内存层面SQL生成自动添加LIMIT子句原样执行完整查询内存消耗只加载分页数据加载全部结果集性能表现稳定高效随数据量线性下降适用场景大数据量小数据量或静态数据RowBounds的三大致命缺陷全量加载即使只需要10条数据也会先查询百万级结果集连接占用大结果集传输期间会长时间占用数据库连接序列化开销所有数据都要经历完整的JDBC反序列化过程3. 生产环境分页方案选型指南经过这次教训我们梳理出不同场景下的分页最佳实践3.1 基础分页SQL LIMIT方案select idselectByPage resultTypeUser SELECT * FROM users ORDER BY create_time DESC LIMIT #{offset}, #{pageSize} /select适用场景数据量在百万级以下不需要跳转到很远的页码如直接跳转到第1000页3.2 高性能分页游标分页-- 第一页 SELECT * FROM users WHERE create_time 2023-01-01 ORDER BY create_time, id LIMIT 10; -- 后续页 SELECT * FROM users WHERE create_time 2023-01-15 14:30:00 OR (create_time 2023-01-15 14:30:00 AND id 1024) ORDER BY create_time, id LIMIT 10;优势对比避免了传统分页的OFFSET性能陷阱适合无限滚动加载场景对数据库压力稳定可控3.3 海量数据分页Elasticsearch方案当单表数据超过千万级时我们采用了以下架构应用服务 → Elasticsearch集群 → 数据库 (分页查询) (全量同步)实施要点使用search_after参数实现深度分页设置合理的分片数和副本数定期执行forcemerge优化查询性能4. MyBatis分页插件实战技巧虽然不推荐使用RowBounds但MyBatis生态中确实存在更智能的分页解决方案4.1 PageHelper正确配置# application.yml pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: countcountSql关键代码示例PageHelper.startPage(1, 10); // 第1页每页10条 ListUser users userMapper.selectAll(); PageInfoUser pageInfo new PageInfo(users);4.2 自定义拦截器实现如果需要更精细的控制可以自定义分页拦截器Intercepts(Signature(type Executor.class, methodquery, args{MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})) public class CustomPageInterceptor implements Interceptor { // 实现分页逻辑改写 }拦截器核心职责检测是否需要分页改写原始SQL添加分页参数执行count查询获取总数返回包装后的分页结果5. 分页性能优化全攻略5.1 数据库层面优化索引设计原则分页查询字段必须建立联合索引ORDER BY子句中的字段顺序决定索引有效性避免在分页字段上使用函数操作查询优化技巧-- 反例无法使用索引 SELECT * FROM users ORDER BY DATE(create_time) DESC LIMIT 100,10; -- 正例 SELECT * FROM users WHERE create_time 2023-01-01 ORDER BY create_time DESC LIMIT 100,10;5.2 应用层缓存策略采用两级缓存架构提升分页性能本地缓存Guava Cache存储热点分页数据CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterWrite(5, TimeUnit.MINUTES) .build();分布式缓存Redis存储分页元数据# Redis分页数据结构示例 HMSET page:users:1 total 1000 pages 100 items 10 data [...]5.3 前端协作优化通过API设计减少不必要的数据传输// 良好设计的分页响应 { data: [...], pagination: { current_page: 1, per_page: 10, total: 1000, has_more: true } }重要约定默认每页不超过50条记录禁止无限制的pageSize0查询对深度分页请求进行限流那次OOM事故后我们花了两个月时间重构了整个分页体系。现在回想起来最大的收获不是技术方案本身而是明白了在软件开发中看似简单的功能往往隐藏着最危险的陷阱。特别是在处理数据访问层时永远要对网上抄来的代码保持警惕因为生产环境从不会对任何人的疏忽手下留情。

相关文章:

MyBatis RowBounds分页踩坑实录:一次线上OOM事故教会我的事

MyBatis分页陷阱:从RowBounds内存泄漏到高效分页实战 凌晨三点,手机突然响起刺耳的报警声。打开监控系统一看,某核心服务的堆内存曲线像坐了火箭一样直线上升,最终触发了OOM崩溃。经过彻夜排查,罪魁祸首竟是项目中一段…...

Java Loom插件部署实录(2024最新版IDEA/Eclipse兼容清单+离线安装包获取通道)

第一章:Java 项目 Loom 响应式编程转型指南Project Loom 与响应式编程并非互斥范式,而是可协同演进的技术路径。Loom 的虚拟线程(Virtual Threads)为传统阻塞式 I/O 密集型响应式栈(如 Spring WebFlux Reactor&#x…...

【Spring Boot 4.0 Agent-Ready 架构终极指南】:20年架构师亲授生产级字节码增强实战秘技

第一章:Spring Boot 4.0 Agent-Ready 架构全景认知Spring Boot 4.0 首次将 JVM Agent 集成能力深度融入核心启动生命周期,标志着可观测性、安全增强与运行时治理从“可选插件”跃迁为“原生契约”。Agent-Ready 并非仅指支持 Java Agent 加载&#xff0c…...

算一笔账:招剪辑师VS用易元AI,一年的成本差距有多大?

电商短视频成本,正在成为压在商家头上的一座隐形大山。在当前环境下,AI省人工成本已经不再是“锦上添花”,而是影响利润结构的关键变量。越来越多团队开始重新审视一个问题:继续招剪辑师,还是用AI替代? 当内…...

当n和L大到1e18时,别再暴力模拟了!详解‘3437 melon’吃瓜问题的O(1)公式推导与边界条件处理

极端数据规模下的算法优化:从暴力模拟到O(1)公式推导 在算法竞赛和高性能编程中,我们常常会遇到数据规模极其庞大的问题。当输入参数达到1e18量级时,传统的暴力模拟或动态规划方法往往无法在合理时间内完成计算。本文将以经典的"3437 me…...

基于西门子S7-1500 PLC的空压站自控系统设计方案

基于西门子S7-1500 PLC的空压站自控系统设计方案 摘 要 本文针对空压站自控系统需求,基于西门子S7-1500系列PLC(可编程逻辑控制器),配合华杰(华茂)分布式I/O模块,设计了一套完整的群控控制方案。系统涵盖10台空压设备通信、水泵变频恒压控制、阀门联动控制及现场控制柜…...

从调试到量产:高通QDCM与QDCM-FF工具链全解析,实现‘千屏一面’的屏幕一致性校准

从调试到量产:高通QDCM与QDCM-FF工具链全解析,实现‘千屏一面’的屏幕一致性校准 在智能手机和平板电脑的制造过程中,屏幕显示质量的一致性一直是困扰硬件工程师的难题。想象一下,当消费者购买同一型号的两台设备,却发…...

AI辅助设计系统定制方案

一、系统概述 本系统旨在打造一套集成平面设计、三维设计、办公管理、CAD设计及视频制作五大核心功能的AI辅助设计平台。系统采用微服务架构,前端基于React + TypeScript + TailwindCSS构建统一的工作台界面,后端各领域能力以独立服务形式部署,通过API网关统一对外提供服务…...

[盖茨同步带] 盖茨 Poly Chain® ADV® 同步带 | ADV 14MGT/19MGT

关键词:盖茨 Poly Chain ADV 型号,同步带 Poly Chain ADV,工业皮带描述:盖茨Poly Chain ADV同步带参数详解,涵盖材质、规格、适配设备及核心优势,专业工业皮带选型参考,支持价格咨询与定制服务&…...

XML 用途

XML 用途 引言 XML(可扩展标记语言)是一种用于存储和传输数据的标记语言。它被广泛应用于互联网和内部系统中,用于数据的表示、存储和交换。本文将详细介绍XML的用途,帮助读者全面了解这一重要的技术。 XML的基本概念 什么是XML? XML是一种标记语言,它使用标签来定义…...

如何在Mac上安装飞秋:跨平台局域网通信的终极解决方案

如何在Mac上安装飞秋:跨平台局域网通信的终极解决方案 【免费下载链接】feiq 基于qt实现的mac版飞秋,遵循飞秋协议(飞鸽扩展协议),支持多项飞秋特有功能 项目地址: https://gitcode.com/gh_mirrors/fe/feiq 还在为Mac与Windows电脑之间…...

如何彻底释放华硕笔记本的隐藏性能?G-Helper轻量控制工具全解析

如何彻底释放华硕笔记本的隐藏性能?G-Helper轻量控制工具全解析 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, …...

内容运营的配图噩梦:我是怎么用工具批量给文章插入图片解决的

如果你经常需要给大量文章加配图,手动操作的效率瓶颈你一定深有体会。上周同事找我帮忙,说他那积压了快三百篇历史文章要重新发布到新平台。这些文章都是纯文本格式,当初写的时候没配图,现在平台要求必须带图才有推荐。他之前试过…...

SVG 文本:设计与实现详解

SVG 文本:设计与实现详解 引言 SVG(可缩放矢量图形)文本是网页设计中常用的元素之一,它允许开发者创建可缩放的文本,并具有丰富的样式和动画效果。本文将详细介绍SVG文本的设计与实现,包括其基本概念、使用方法以及在实际项目中的应用。 SVG文本的基本概念 1. SVG简介…...

如何防御SQL注入恶意代码_对上传文件执行严格过滤

...

Linux设备树实战:如何为IMX6ULL开发板定制dts文件(附完整编译流程)

Linux设备树实战:如何为IMX6ULL开发板定制dts文件(附完整编译流程) 在嵌入式Linux开发中,设备树(Device Tree)已经成为硬件描述的标准方式。对于使用NXP i.MX6ULL处理器的开发者来说,掌握设备树…...

SAP PP生产订单状态管理实战:从系统状态到用户状态,手把手教你配置审批流与差异控制

SAP PP生产订单状态管理实战:从系统状态到用户状态深度配置指南 在制造业数字化转型浪潮中,SAP PP模块作为生产计划与执行的中枢神经,其订单状态管理能力直接决定了企业生产流程的精细度与合规性。不同于基础教程对状态概念的简单罗列&#x…...

企业网站设计|网站建设公司哪家好?2026十家网站制作公司深度盘点

在数字经济与产业融合持续推进的当下,企业网站不再是单一的线上展示窗口,而是承载品牌形象、业务衔接、用户交互的核心数字化载体。2026 年,国内网站建设行业逐步完成从模板化搭建到定制化开发的转型,多终端适配、数据安全防护、多…...

大师之上,再造大师:玲珑轮胎“三个向上”战略的深度解码

4月16日,玲珑大师二代轮胎如约而至。这不仅仅是一款新品的亮相,更是玲珑轮胎在五十年发展长河中,对“中国第一,世界一流”这一目标的又一次庄严兑现。 玲珑轮胎总裁周令坤在发布会上,将玲珑的战略路径凝练为“三个向上…...

【限时首发|内部白皮书节选】Spring Boot 4.0 Agent-Ready架构设计规范V1.2(含12个不可绕过的SPI扩展点与8个已知CVE规避方案)

第一章:Spring Boot 4.0 Agent-Ready架构的演进背景与核心定位随着云原生可观测性标准(OpenTelemetry、eBPF、W3C Trace Context)的成熟,以及Java平台对JVM TI、JVMTI Attach API和Instrumentation API的持续增强,传统…...

Rust Trait 对象的动态派发

Rust Trait对象的动态派发:灵活多态的实现之道 在Rust中,Trait对象是实现运行时多态的核心机制之一。与静态派发不同,动态派发通过Trait对象在运行时决定调用哪个具体实现,为代码提供了更大的灵活性。这种机制尤其适合需要处理多…...

医用电气环境测试GB/T 14710-2009实战解读

做医疗器械注册、检测和研发的人,基本都绕不开 GB/T 14710-2009。它不只是一份合规标准,更是医用电气设备的环境适应性 “生存考试”,专门验证设备在医院、库房、运输途中能不能稳定扛住各种工况。标准把设备按气候环境和运输强度分成 Ⅰ、Ⅱ…...

基于STM32LXXX的无线收发芯片(SI4732-A10-GSR)应用程序设计

一、简介: Si4732-A10数字CMOS调幅/调频/短波/低频/射频数字接收器集成电路,实现了从天线输入端到数字音频输出端的完整广播调谐与接收功能。该器件采用Silicon Labs经过广播验证的数字低中频架构,为消费电子应用提供高性价比的数字音频平台,具备优异的时分多址抗噪能力、卓…...

基于STM32LXXX的无线收发芯片(Ci24R1)应用程序设计

一、简介: Ci24R1 是南京中科微推出的一款工作在 2.4GHz ISM 频段的 GFSK/FSK 无线收发芯片。它在设计上高度兼容 nRF24L01+ 的寄存器映射,常被视为低成本替代方案,同时增加了与 BLE4.2 的物理层兼容性 。 二、主要技术特性: ◼ 工作在2.4GHz ISM频段 ◼ 调制方式:GFSK…...

南北阁Nanbeige4.1-3B计算机组成原理:CPU设计模拟

南北阁Nanbeige4.1-3B计算机组成原理:CPU设计模拟 计算机组成原理是计算机科学的核心课程,但传统教学往往停留在理论层面,学生很难真正理解CPU是如何工作的。南北阁Nanbeige4.1-3B模型为这门课程带来了全新的教学体验。 1. 计算机组成原理的教…...

压力测试工具 JMeter 使用教程

## 压力测试工具JMeter使用教程 在当今互联网高速发展的时代,确保系统在高并发情况下的稳定性至关重要。Apache JMeter 是一款开源的性能测试工具,广泛应用于Web应用、数据库、API等场景的压力测试。它功能强大,支持多协议测试,并…...

跨站脚本攻击(XSS)深度剖析:从原理到实战绕过及防御体系

时间:2026年4月 | 仅限技术交流与学习 一、XSS漏洞简介与危害 跨站脚本攻击(Cross Site Scripting,缩写为XSS)是一种常见的Web安全漏洞,攻击者通过在网页中注入恶意脚本代码,当用户浏览页面时…...

向量搜索查询返回空结果却无异常?EF Core 10中CosineSimilarity表达式树编译失败的静默降级机制揭秘

第一章:向量搜索查询返回空结果却无异常?EF Core 10中CosineSimilarity表达式树编译失败的静默降级机制揭秘现象复现与根本诱因 在 EF Core 10 中调用 CosineSimilarity 方法进行向量相似度检索时,若底层数据库(如 PostgreSQL pg…...

不同场景做MV该用什么工具?OhYesAI、VidMuse、Kaiber、Runway选型指南

核心前提结论:选择MV制作工具第一步,需要先明确核心需求是「给音乐配画面」还是「把内容做成视频」,两类需求对应完全不同的工具类型,选错工具无法解决核心问题。1. 独立音乐人/音乐博主MV工具选型 核心结论:独立音乐人…...

告别C盘!手把手教你将Node.js 16.15.1安装到D盘并配置全局模块路径

彻底解放C盘空间:Node.js 16.15.1自定义安装与全局模块管理全攻略 当你的C盘开始频繁弹出空间不足的警告,而Node.js的全局模块又像野草一样在系统目录疯长时,是时候重新思考开发环境的布局策略了。本文将带你深入探索如何将Node.js 16.15.1完…...