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

MyBatis 批量插入优化:百万数据秒级导入

作为一名奋战在一线的后端开发工程师数据库批量操作是我们几乎每天都会遇到的场景。无论是数据迁移、定时报表计算还是日志存档我们都免不了要和“插入大量数据”打交道。不知道你是否曾有过这样的经历系统上线初期数据量不大一切风平浪静。然而随着业务扩张某天你写了一个简单的for循环调用mapper.insert()准备插入几十万条数据。你点击了运行然后去接了一杯咖啡回来后发现程序还在跑你吃完午饭回来发现它居然还在跑看着控制台那漫长的时间你陷入了沉思为什么这么慢在网络上我们经常看到“MyBatis批量插入秒级导入百万数据”的说法。这到底是标题党的噱头还是确有其事今天我们就抛开那些含糊其辞的言论深入MyBatis与JDBC的底层结合真实的实测数据5万、10万、100万级别彻底解开批量插入的性能之谜。声明本文所有结论均基于MySQL 8.0数据库、MyBatis 3.x/MyBatis-Plus框架以及JDBC驱动源码分析得出数据来源均为开发者社区公开的实测记录及笔者验证确保真实可靠。第一章直观的冲击——为什么“逐条插入”是性能杀手在开始优化之前我们必须先认清“慢”的本质。很多新手最直观的写法就是在Java代码中使用for循环然后反复调用同一个插入方法。这种写法在数据量较小时如几十条毫无感觉但一旦数据量上升到5万条灾难就降临了。根据开发者社区的实测数据使用for循环单条插入5万条数据平均耗时达到了惊人的177秒接近3分钟。按照这个比例推算插入100万条数据需要3540秒也就是将近1个小时。为什么这么慢底层原理解析这是由以下几个方面的开销叠加导致的网络传输的“惊群效应”Java应用与MySQL数据库之间通过网络通信。每一次insert语句的执行都相当于客户端给服务端发送一个“包裹”。发送5万个包裹哪怕每个包裹只有1KB光是网络IO的握手、传输、确认就要消耗大量的时间。网络延迟在高频交互下被急剧放大。SQL解析的“重复造轮子”在MySQL执行SQL前需要经过词法解析、语法解析、生成执行计划等步骤。在逐条插入模式下同样的SQL语句只是值不同被解析了5万次。MySQL查询缓存虽然能缓解但对于写操作Insert缓存是失效的这意味着这5万次解析完全是重复劳动。事务提交的“刷盘压力”在Spring Boot默认配置或手动编程事务中每执行一条SQL如果没有特殊配置往往伴随着一次自动提交AutoCommittrue。这意味着每次插入不仅要写内存还要确保日志写入磁盘。磁盘I/O是计算机中最慢的环节之一5万次磁盘同步写操作足以拖垮任何高性能服务器。结论要想达到“秒级”导入核心目标只有一个尽一切可能减少Java程序与数据库之间的交互次数。第二章初窥门径——foreach拼接SQL的“大包干”模式既然交互次数是瓶颈最直观的解决方案就是把多条SQL塞成一条超级大的SQL一次性发过去。这就是MyBatis中最常见的foreach标签批量插入方式。1. 实现原理将多次网络请求合并为一次通过在Mapper.xml中编写动态SQL将List集合中的循环直接拼接在values后面。sqlINSERT INTO table (col1, col2) VALUES (1,2), (3,4), (5,6)...2. 实测数据性能的飞跃同样是5万条数据的插入测试使用拼接SQL的方式耗时直接从177秒降低到了2.9秒左右。这个提升是质的飞跃从“吃个饭回来还在跑”变成了“刚坐下就结束了”。3. 隐藏的“深坑”数据库报文大小限制与内存溢出既然foreach这么强是不是可以无脑用并不是。当数据量达到百万级时这种方法会暴露出严重的弊端。SQL长度限制MySQL数据库有一个max_allowed_packet参数默认通常是4M。当你一次性拼接的SQL字符串超过这个大小数据库会直接拒绝连接或抛出异常。真实案例有开发者尝试使用foreach一次性插入10万条记录涉及20多个字段生成的SQL文本大小高达4.56M直接触发了MySQL的PacketTooBigException。解析复杂度指数级增长并不是SQL越长越好。MyBatis底层在处理长SQL时需要构建巨大的字符串并映射占位符。MySQL解析一个包含10万个values的语句其内存消耗和解析时间是指数级上升的。有资料指出当values数量超过5000后性能曲线会急剧下跌。小结foreach适用于中小批量如单次500-1000条的数据同步但绝对不能用于百万级的一次性导入。第三章官方秘籍——揭开ExecutorType.BATCH的神秘面纱那么既要减少网络交互又要避免SQL体积爆炸该怎么办其实MyBatis早就提供了官方的解决方案——Batch Executor。1. 重新认识MyBatis的执行器MyBatis有三种内置的Executor类型默认是SIMPLESIMPLE每次执行都会创建一个新的预处理语句PreparedStatement执行完即关闭。这就是我们for循环慢的原因。REUSE会复用PreparedStatement但依然是一条一条发往数据库。BATCH专门用于批量操作的执行器。2. BATCH模式的工作原理开启ExecutorType.BATCH后MyBatis的行为发生了底层变化缓存SQL当连续执行多条SQL时如果SQL语句结构相同MyBatis不会立即发送而是将它们缓存在batch缓冲区中。预编译优化PreparedStatement只会被创建一次后续的插入只是不断设置参数。批量发送当你调用sqlSession.commit()或达到一定数量时MyBatis会一次性将这批参数连同SQL发送给数据库。3. 实战测试这才是“秒级”的真正含义使用ExecutorType.BATCH模式并关闭自动提交插入5万条数据实测耗时为1.7秒左右。在更高量级的测试中10万条数据普通的saveBatchMP默认实现需要20秒而开启了BATCH模式优化后仅需5秒左右。这是目前公认的、在MyBatis框架下针对百万数据量级的最优解。第四章点睛之笔——rewriteBatchedStatements被忽视的王牌参数有时候哪怕你用了上面的BATCH模式发现性能并没有质的飞跃比如只是从100秒变成了60秒依然达不到秒级。这时候90%的原因是你缺少了一个关键的JDBC参数rewriteBatchedStatementstrue。1. 这就是为什么你的“批量”没生效MySQL的JDBC驱动在默认情况下出于对某些数据库兼容性或者保守策略的考虑会忽略executeBatch()命令。当你调用addBatch()时驱动心里想的是“虽然你让我攒一批但我还是习惯一条一条发给数据库。”没有这个参数你的BATCH模式只是把SQL攒在了一起发送的时候依然是for循环发送。2. 参数开启后的质变在连接URL后面加上?rewriteBatchedStatementstruepropertiesjdbc:mysql://localhost:3306/test?rewriteBatchedStatementstrue开启后JDBC驱动会做一件非常聪明的事情它会把你的批量操作“重写”为一条原生的多重VALUES的Insert语句。开启前驱动向数据库发送Insert into ... values (?)Insert into ... values (?)...开启后驱动将上述内容重写为Insert into ... values (?), (?) ...对比数据在未开启此参数时10万条数据插入耗时约20秒开启后耗时骤降至5秒甚至更优。这才是真正物理意义上的“合并发送”。第五章分而治之——百万级数据的架构策略现在我们已经拿到了BATCH模式 rewriteBatchedStatements这把利器。但在百万级数据面前即便是最锋利的武器也需要讲究战术。如果你试图在一个事务中一次性处理100万条数据可能会遇到两个新问题内存溢出List集合持有100万个对象占用大量堆内存引发频繁GC。长事务陷阱一个事务运行数十分钟会导致Undo日志膨胀甚至拖垮主从复制。因此对于百万级导入我们必须引入“分片”思想。1. 手动分片策略原理很简单将大List切分成若干个小List。比如我们要插入100万条数据设置批次处理大小为1000。将100万数据拆分成1000个“分片”。对每个分片执行一次BATCH级别的插入操作。每个分片单独开启和提交事务或者批量提交事务。2. 批次大小的“黄金分割点”批次大小单次提交的记录数并非越大越好。过小如10条网络交互次数依然很多优势不明显。过大如10万条虽然网络交互少了但单条SQL即使使用BATCH在数据库端执行时间过长且会占用巨大的数据库内存。最佳实践经过大量测试500条到2000条之间是性价比最高的区间。若单行数据很小如只有ID和Name可偏向2000-5000条。若单行数据很大如包含Text或Blob字段建议降低到500-1000条。结论百万数据导入 分片逻辑BATCH执行器rewriteBatchedStatementstrue。第六章实战中的避坑指南与“极端”优化在实际生产环境中除了上述核心配置还有一些细节决定了最终的成败。1. 自增主键回填的性能损耗如果你需要在插入后获得数据库自动生成的主键IDuseGeneratedKeystrue这会对批量插入产生一定的性能影响。因为数据库需要逐条生成ID并返回给客户端破坏了“流式”传输的连续性。优化建议如果你的导入场景只是归档数据Log或流水且不需要立即获取ID可以考虑在数据库层面不依赖自增ID或者使用雪花算法在客户端提前生成ID。这能微幅提升批量插入效率。2. 表结构与索引的取舍索引的代价插入数据时数据库不仅要写数据还要更新索引BTree。数据量越大索引维护的开销越大。优化方案对于超大数据的离线导入ETL一种极端优化是先删除或禁用索引导入数据重建索引。在百万级数据场景下这种方式往往比边插边建索引快得多。3. 调整MySQL数据库参数为了让数据库承受住批量写入需要配合调整MySQL配置innodb_buffer_pool_size设置足够大尽可能容纳数据和索引减少磁盘I/O。innodb_log_file_size增大日志文件大小减少日志切换带来的检查点开销。max_allowed_packet如果使用foreach方案虽然不推荐必须调大此参数以容纳大SQL。第七章不同方案的横向对比与选型建议为了给你一个更直观的参考我们将几种方案整理为下表基于10万条数据方案实现方式耗时约优点缺点适用场景逐条插入for insert350秒实现简单极慢资源消耗大严禁使用于批量场景MyBatis-PlussaveBatch()20秒无需写SQL开箱即用默认配置下性能不佳中小规模数据对性能不敏感拼接SQLforeach3-10秒比逐条快直观受SQL长度限制大数据量内存爆炸单次1000条以内的小批量终极BATCHBATCH rewrite2-5秒性能最优资源可控需手动配置需注意分片生产环境大规模数据迁移首选结语回归业务的本质经过一系列的技术拆解我们可以看到所谓“百万数据秒级导入”并非天方夜谭。从底层的网络IO、预编译原理到JDBC驱动的隐藏参数再到架构层的分片策略每一步优化都有扎实的理论依据。在追求性能的道路上我们往往热衷于寻找“银弹”。但希望这篇文章能让你明白真正的优化没有银弹只有对底层原理的深刻理解。下次当你面对海量数据插入任务时请记住这几步丢掉for循环单条插入。拥抱ExecutorType.BATCH。检查JDBC URL中的rewriteBatchedStatementstrue。记得将列表分片提交。希望这篇博客能帮助你彻底解决MyBatis批量插入的性能痛点让你在处理大数据时更有底气。如果你在实际调优中遇到了奇葩的“坑”欢迎在评论区留言交流。

相关文章:

MyBatis 批量插入优化:百万数据秒级导入

作为一名奋战在一线的后端开发工程师,数据库批量操作是我们几乎每天都会遇到的场景。无论是数据迁移、定时报表计算,还是日志存档,我们都免不了要和“插入大量数据”打交道。不知道你是否曾有过这样的经历:系统上线初期&#xff0…...

vConTACT3: 机器学习实现可扩展和系统的病毒层级分类

https://www.nature.com/articles/s41587-025-02946-9 https://bitbucket.org/MAVERICLab/vcontact3/src/master/ 安装 mamba create --name vcontact3 python3.10 mamba activate vcontact3 #Or 最新版 cd Software git clone https://bitbucket.org/MAVERICLab/vcontact3.…...

VL6180X不止能测距!手把手教你在STM32上读取环境光强度(ALS)

VL6180X环境光传感实战:从寄存器配置到Lux值转换的完整指南 在智能设备开发中,环境光传感(ALS)功能正变得越来越重要。无论是自动调节屏幕亮度,还是根据光照条件优化设备功耗,精确的光强检测都是实现这些功能的基础。VL6180X作为一…...

告别Arduino IDE!用VSCode+PlatformIO搭建ESP32开发环境(2024保姆级教程,含Python配置避坑)

从Arduino到VSCode:2024年ESP32高效开发环境全指南 当你在Arduino IDE中频繁切换标签页、手动管理第三方库、忍受着简陋的代码补全时,是否想过开发工具本可以更智能?2024年的嵌入式开发早已进入现代化工具链时代,而VSCodePlatfor…...

iPhone充电慢怎么办?6个方法大幅缩短充电时间!

iPhone充电慢问题由来已久 这是个由来已久的问题(至少从2007年就开始了):你买了一部新iPhone来享受最新、最棒的功能,但随着时间推移,突然有一天你会觉得手机电量怎么都充不满,电池老是没电。另外&#xff…...

如何快速上手ComfyUI-Florence2视觉语言模型:新手完整配置指南

如何快速上手ComfyUI-Florence2视觉语言模型:新手完整配置指南 【免费下载链接】ComfyUI-Florence2 Inference Microsoft Florence2 VLM 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Florence2 你是否想在ComfyUI中体验强大的视觉语言模型Florence…...

告别 pip install 失败:手把手教你为 Jetson 的特定 Python 环境源码安装 PyCUDA

告别 pip install 失败:手把手教你为 Jetson 的特定 Python 环境源码安装 PyCUDA 在 Jetson 开发板上配置深度学习环境时,PyCUDA 是一个绕不开的关键组件。然而,许多开发者都遇到过这样的尴尬场景:满怀信心地输入 pip install pyc…...

人工智能(九)- Spring AI MCP客户端开发

人工智能(八)- Spring AI 开发MCP Server(Streamable HTTP)完整开发与测试 一、MCP 客户端 上一篇我们开发了MCP Server,现在来开发MCP Client。 通过 MCP Client 向服务器请求工具列表,服务器返回所有工…...

小身材,大能耐!RT-Thread BK7252 麻雀一号开发板全功能实战解析

1. 麻雀一号开发板:小身材藏着大能量 第一次拿到RT-Thread麻雀一号开发板时,我差点以为这是个玩具——它的尺寸只有信用卡的三分之二大小。但当我翻开规格书,才发现这个"小不点"竟然集成了BK7252主控芯片、WiFi/BLE双模模块、30万像…...

Vivado比特流压缩:一个Tcl命令让你的FPGA配置文件缩小一半(附完整脚本)

Vivado比特流压缩实战:从原理到脚本的完整优化方案 在嵌入式FPGA开发中,存储空间往往是稀缺资源。想象一下,当你精心设计的逻辑即将部署到现场,却因为比特流文件过大而不得不更换更大容量的Flash芯片——这不仅增加成本&#xff…...

ESP32接PS2手柄总失败?手把手教你修改Arduino库并上传GitHub(附完整代码)

ESP32与PS2手柄深度适配指南:从源码修改到开源贡献全流程 1. 项目背景与问题定位 去年在开发一个机器人遥控项目时,我遇到了一个棘手的问题:ESP32开发板始终无法稳定识别PS2手柄。经过72小时的反复测试,最终发现问题的根源在于一个…...

ParsecVDisplay:如何用虚拟显示器打破物理屏幕的限制?

ParsecVDisplay:如何用虚拟显示器打破物理屏幕的限制? 【免费下载链接】parsec-vdd ✨ Perfect virtual display for game streaming 项目地址: https://gitcode.com/gh_mirrors/pa/parsec-vdd 你是否曾经因为电脑屏幕不够用而感到困扰&#xff1…...

【Python】bisect 模块实战:从原理到高效应用

1. 二分查找原理与bisect模块的诞生 二分查找算法就像我们小时候玩的"猜数字"游戏:对方心里想一个1-100的数字,你每次猜中间值,根据"大了"或"小了"的提示缩小范围。bisect模块正是将这个经典算法封装成了Pytho…...

从零电流钳位到精准补偿:深入解析电机死区补偿的两种核心算法

1. 电机死区现象的本质剖析 第一次调试无刷电机驱动器时,我盯着示波器上那些扭曲的电流波形整整三天没想明白——明明PWM占空比计算完全正确,为什么电机低速运转时总会出现规律性的抖动?直到把电流探头挂在相线上,才在过零点附近捕…...

本地AI字幕提取器:一键将视频硬字幕转为可编辑SRT文件

本地AI字幕提取器:一键将视频硬字幕转为可编辑SRT文件 【免费下载链接】video-subtitle-extractor 视频硬字幕提取,生成srt文件。无需申请第三方API,本地实现文本识别。基于深度学习的视频字幕提取框架,包含字幕区域检测、字幕内容…...

大麦网抢票终极指南:Python自动化脚本让你告别抢票焦虑

大麦网抢票终极指南:Python自动化脚本让你告别抢票焦虑 【免费下载链接】DamaiHelper 大麦网演唱会演出抢票脚本。 项目地址: https://gitcode.com/gh_mirrors/dama/DamaiHelper 还在为抢不到心仪演唱会门票而烦恼吗?每次热门演出开票时&#xff…...

单网线搞定供电与传输——POE温湿度变送器集成应用解析

以太网POE供电温湿度变送器在系统集成中的应用摘要:以太网 POE 供电温湿度变送器,凭借 “单网线供电 数据传输” 的一体化优势,完美解决传统温湿度监测设备布线复杂、供电不稳、集成困难等痛点,已成为数据中心、智慧楼宇、工业自…...

3个关键步骤快速上手Fiji:科研图像分析的完整解决方案

3个关键步骤快速上手Fiji:科研图像分析的完整解决方案 【免费下载链接】fiji A "batteries-included" distribution of ImageJ :battery: 项目地址: https://gitcode.com/gh_mirrors/fi/fiji Fiji科学图像处理平台是ImageJ的增强版本,专…...

Joy-Con Toolkit技术架构深度解析:开源手柄控制与传感器校准实现

Joy-Con Toolkit技术架构深度解析:开源手柄控制与传感器校准实现 【免费下载链接】jc_toolkit Joy-Con Toolkit 项目地址: https://gitcode.com/gh_mirrors/jc/jc_toolkit Joy-Con Toolkit是一款专为任天堂Joy-Con和Pro手柄设计的开源控制工具,通…...

5分钟搞定B站视频转文字:bili2text完整指南

5分钟搞定B站视频转文字:bili2text完整指南 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 还在为B站精彩视频的内容整理而烦恼吗?每次…...

终极Windows清理指南:快速解决C盘爆红问题

终极Windows清理指南:快速解决C盘爆红问题 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服! 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 你的Windows电脑是否经常出现C盘空间不足的警告&#xff1f…...

第22篇:AI配音实战——用ElevenLabs克隆你的声音,制作有声内容(操作教程)

文章目录前言环境准备:注册与“氪金”策略分步操作:从克隆到生成第一步:创建你的声音克隆第二步:使用克隆声音生成语音第三步:下载与后期处理完整代码示例:API调用实战踩坑提示:我走过的弯路&am…...

优化Vscode终端缓冲区设置:突破历史记录限制的实用技巧

1. 为什么你的Vscode终端总是丢失历史记录? 每次在Vscode终端里调试代码时,最让人抓狂的就是向上翻看历史记录时突然卡住,发现前面的输出内容全都消失了。这个问题我遇到过无数次,特别是在跑长时间任务或者输出大量日志时。其实这…...

如何用AlienFX Tools完全掌控你的Alienware灯光与风扇:5分钟快速入门指南

如何用AlienFX Tools完全掌控你的Alienware灯光与风扇:5分钟快速入门指南 【免费下载链接】alienfx-tools Alienware systems lights, fans, and power control tools and apps 项目地址: https://gitcode.com/gh_mirrors/al/alienfx-tools 厌倦了Alienware …...

第21篇:Midjourney进阶咒语库——精准控制风格、构图与细节的秘籍(操作教程)

文章目录前言环境准备:理解Midjourney的“语言规则”分步操作:构建你的三维度咒语库第一步:风格控制——决定画面的“基因”1. 艺术风格与流派2. 媒介与材质3. 时代与地区风格第二步:构图控制——成为画面的“导演”1. 镜头与景别…...

Labelme AI-Polygon闪退别慌!手把手教你用修改版5.3.1一键搞定(附模型下载)

Labelme AI-Polygon闪退终极解决方案:修改版5.3.1实战指南 当你第一次尝试用Labelme的AI-Polygon功能标注图像时,那种期待感可能很快会被闪退提示框击碎。别担心,这几乎是每个数据标注新手的必经之路——环境配置、模型路径、依赖版本&#x…...

正规机构开锁电话

生活中,门锁故障、钥匙丢失等突发状况时有发生,找到正规开锁机构才能避免安全隐患与不必要的纠纷。惠州市惠城区罗记开锁中心是经公安备案、工商注册的专业开锁单位,具备完善的资质与丰富的实操经验,为惠州地区的居民和商户提供可…...

OpenVAS_gsm_4.3.14在VirtualBox中的部署与配置指南

1. OpenVAS_gsm_4.3.14简介与准备工作 OpenVAS(开放式漏洞评估系统)是目前最受欢迎的开源漏洞扫描工具之一,它的核心价值在于能够帮助安全测试人员快速发现网络系统中的安全隐患。我最早接触OpenVAS是在2015年的一次企业内网渗透测试项目中&a…...

DamaiHelper:大麦网智能抢票自动化脚本解决方案

DamaiHelper:大麦网智能抢票自动化脚本解决方案 【免费下载链接】DamaiHelper 大麦网演唱会演出抢票脚本。 项目地址: https://gitcode.com/gh_mirrors/dama/DamaiHelper 还在为抢不到热门演唱会门票而烦恼吗?DamaiHelper大麦抢票脚本是一个基于P…...

告别混乱:用FatFS为你的ESP32物联网项目构建可靠的文件存储方案

告别混乱:用FatFS为你的ESP32物联网项目构建可靠的文件存储方案 在物联网设备开发中,数据管理往往是最容易被忽视却又最令人头疼的问题。想象一下,你的ESP32设备正在稳定运行,突然因为一个简单的文件写入错误导致整个系统崩溃&…...