最新要闻
- 世界观点:被曝北约考虑在日设联络处后,岸田宣称日本没有加入北约计划
- 苦等几十年!Windows终于原生支持rar、7z等格式压缩文件了|全球视点
- 车标贴满全身!梅赛德斯-迈巴赫Night Series官图发布:真奢华
- 【全球聚看点】699元 联想YOGA K7机械键盘上架:82键矮轴 真空电镀工艺
- AI网聊10分钟被骗430万 中国互联网协会给出防范建议
- 环球今头条!国内多航司现千元内国际机票 上海直飞日本仅600元
- 西部决赛:掘金淘汰洛杉矶湖人的背后,藏着多少鲜为人知的秘密-热消息
- 安卓不再清后台 OPPO Reno10系列用上16GB大内存:48个月流畅
- Find系列同款!OPPO Reno10 Pro搭载动态光影屏:120Hz高刷
- 视点!不怕别人超越!“比亚迪魔方”储能系统发布:首搭刀片电池
- 环球新消息丨349元 OPPO Enco R2耳机发布:Hi-Fi级处理芯片
- 支付宝提醒“学生账户升级”骗局:没有学生/成人账户概念!
- 社区工作者感受垃圾分类处理全过程
- 北京西京医院杨博华_北京西京医院
- 64核CPU、显卡三连冠 AMD超算屠榜:唯一一台百亿亿次
- 国产SSD卷疯了!梵想S500 Pro 2TB只要409元 观天下
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
【MyBatis】saveBatch 性能调优|即时焦点
这个项目用的是 mybatis-plus,批量保存直接用的是 mybatis-plus 提供的 saveBatch。 我点进去看了下源码,感觉有点不太对劲:
继续追踪了下,从这个代码来看,确实是 for 循环一条一条执行了 sqlSession.insert,下面的 consumer 执行的就是上面的 sqlSession.insert:
(相关资料图)
然后累计一定数量后,一批 flush。从这点来看,这个 saveBach 的性能肯定比直接一条一条 insert 快。
我直接进行一个粗略的实验,简单创建了一张表来对比一波!
1、1000条数据,一条一条插入
@Testvoid MybatisPlusSaveOne() { SqlSession sqlSession = sqlSessionFactory.openSession(); try { StopWatch stopWatch = new StopWatch(); stopWatch.start("mybatis plus save one"); for (int i = 0; i < 1000; i++) { OpenTest openTest = new OpenTest(); openTest.setA("a" + i); openTest.setB("b" + i); openTest.setC("c" + i); openTest.setD("d" + i); openTest.setE("e" + i); openTest.setF("f" + i); openTest.setG("g" + i); openTest.setH("h" + i); openTest.setI("i" + i); openTest.setJ("j" + i); openTest.setK("k" + i); //一条一条插入 openTestService.save(openTest); } sqlSession.commit(); stopWatch.stop(); log.info("mybatis plus save one:" + stopWatch.getTotalTimeMillis()); } finally { sqlSession.close(); }}
可以看到,执行一批 1000 条数的批量保存,耗费的时间是 121011 毫秒。
2、1000条数据用 mybatis-plus 自带的 saveBatch 插入
@Testvoid MybatisPlusSaveBatch() { SqlSession sqlSession = sqlSessionFactory.openSession(); try { ListopenTestList = new ArrayList<>(); for (int i = 0; i < 1000; i++) { OpenTest openTest = new OpenTest(); openTest.setA("a" + i); openTest.setB("b" + i); openTest.setC("c" + i); openTest.setD("d" + i); openTest.setE("e" + i); openTest.setF("f" + i); openTest.setG("g" + i); openTest.setH("h" + i); openTest.setI("i" + i); openTest.setJ("j" + i); openTest.setK("k" + i); openTestList.add(openTest); } StopWatch stopWatch = new StopWatch(); stopWatch.start("mybatis plus save batch"); //批量插入 openTestService.saveBatch(openTestList); sqlSession.commit(); stopWatch.stop(); log.info("mybatis plus save batch:" + stopWatch.getTotalTimeMillis()); } finally { sqlSession.close(); }}
耗费的时间是 59927 毫秒,比一条一条插入快了一倍,从这点来看,效率还是可以的。
然后常见的还有一种利用拼接 SQL 方式来实现批量插入,我们也来对比试试看性能如何。
3、1000 条数据用手动拼接 SQL 方式插入, 搞个手动拼接:
来跑跑下性能如何:
@Testvoid MapperSaveBatch() { SqlSession sqlSession = sqlSessionFactory.openSession(); try { ListopenTestList = new ArrayList<>(); for (int i = 0; i < 1000; i++) { OpenTest openTest = new OpenTest(); openTest.setA("a" + i); openTest.setB("b" + i); openTest.setC("c" + i); openTest.setD("d" + i); openTest.setE("e" + i); openTest.setF("f" + i); openTest.setG("g" + i); openTest.setH("h" + i); openTest.setI("i" + i); openTest.setJ("j" + i); openTest.setK("k" + i); openTestList.add(openTest); } StopWatch stopWatch = new StopWatch(); stopWatch.start("mapper save batch"); //手动拼接批量插入 openTestMapper.saveBatch(openTestList); sqlSession.commit(); stopWatch.stop(); log.info("mapper save batch:" + stopWatch.getTotalTimeMillis()); } finally { sqlSession.close(); }}
耗时只有 2275 毫秒,性能比 mybatis-plus 自带的 saveBatch 好了 26 倍!
这时,我又突然回想起以前直接用 JDBC 批量保存的接口,那都到这份上了,顺带也跑跑看!
4、1000 条数据用 JDBC executeBatch 插入
@Testvoid JDBCSaveBatch() throws SQLException { SqlSession sqlSession = sqlSessionFactory.openSession(); Connection connection = sqlSession.getConnection(); connection.setAutoCommit(false); String sql = "insert into open_test(a,b,c,d,e,f,g,h,i,j,k) values(?,?,?,?,?,?,?,?,?,?,?)"; PreparedStatement statement = connection.prepareStatement(sql); try { for (int i = 0; i < 1000; i++) { statement.setString(1,"a" + i); statement.setString(2,"b" + i); statement.setString(3, "c" + i); statement.setString(4,"d" + i); statement.setString(5,"e" + i); statement.setString(6,"f" + i); statement.setString(7,"g" + i); statement.setString(8,"h" + i); statement.setString(9,"i" + i); statement.setString(10,"j" + i); statement.setString(11,"k" + i); statement.addBatch(); } StopWatch stopWatch = new StopWatch(); stopWatch.start("JDBC save batch"); statement.executeBatch(); connection.commit(); stopWatch.stop(); log.info("JDBC save batch:" + stopWatch.getTotalTimeMillis()); } finally { statement.close(); sqlSession.close(); }}
耗时是 55663 毫秒,所以 JDBC executeBatch 的性能跟 mybatis-plus 的 saveBatch 一样(底层一样)。
综上所述,拼接 SQL 的方式实现批量保存效率最佳。
但是我又不太甘心,总感觉应该有什么别的法子,然后我就继续跟着 mybatis-plus 的源码 debug 了一下,跟到了 MySQL 的驱动,突然发现有个 if 里面的条件有点显眼:
就是这个叫 rewriteBatchedStatements 的玩意,从名字来看是要重写批操作的 Statement,前面batchHasPlainStatements 已经是 false,取反肯定是 true,所以只要这参数是 true 就会进行一波操作。
我看了下默认是 false。
同时我也上网查了下 rewriteBatchedStatements 参数,好家伙,好像有用!
直接将 jdbcurl 加上了这个参数:
然后继续跑了下 mybatis-plus 自带的 saveBatch,果然性能大大提高,跟拼接 SQL 差不多!
顺带我也跑了下 JDBC 的 executeBatch ,果然也提高了。
然后我继续 debug ,来探探 rewriteBatchedStatements 究竟是怎么 rewrite 的! 如果这个参数是 true,则会执行下面的方法且直接返回:
看下 executeBatchedInserts 究竟干了什么:
看到上面我圈出来的代码没,好像已经有点感觉了,继续往下 debug。
果然!SQL 语句被 rewrite了:
对插入而言,所谓的 rewrite 其实就是将一批插入拼接成 insert into xxx values (a),(b),(c)...这样一条语句的形式然后执行,这样一来跟拼接 SQL 的效果是一样的。
那为什么默认不给这个参数设置为 true 呢?主要有以下两点:
如果批量语句中的某些语句失败,则默认重写会导致所有语句都失败。
批量语句的某些语句参数不一样,则默认重写会使得查询缓存未命中。
看起来影响不大,所以我给我的项目设置上了这个参数!
最后
稍微总结下我粗略的对比(虽然粗略,但实验结果符合原理层面的理解),如果你想更准确地做实验,可以使用 JMH,并且测试更多组数(如 5000,10000等)的情况。
所以如果有使用 JDBC 的 Batch 性能方面的需求,要将 rewriteBatchedStatements 设置为 true,这样能提高很多性能。
然后如果喜欢手动拼接 SQL 要注意一次拼接的数量,分批处理。
关键词:
【MyBatis】saveBatch 性能调优|即时焦点
世界观点:被曝北约考虑在日设联络处后,岸田宣称日本没有加入北约计划
苦等几十年!Windows终于原生支持rar、7z等格式压缩文件了|全球视点
车标贴满全身!梅赛德斯-迈巴赫Night Series官图发布:真奢华
【全球聚看点】699元 联想YOGA K7机械键盘上架:82键矮轴 真空电镀工艺
AI网聊10分钟被骗430万 中国互联网协会给出防范建议
环球今头条!国内多航司现千元内国际机票 上海直飞日本仅600元
西部决赛:掘金淘汰洛杉矶湖人的背后,藏着多少鲜为人知的秘密-热消息
es之增删改查 每日播报
顶象全新金融业务安全方案,亮相亚太银行数字化峰会
Java开启异步的两种方式
Python文件读写、StringIO和BytesIO_每日速看
动态:Ruby教程_编程入门自学教程_菜鸟教程-免费教程分享
【环球新要闻】【新华500】新华500指数(989001)24日下跌1.28%
安卓不再清后台 OPPO Reno10系列用上16GB大内存:48个月流畅
Find系列同款!OPPO Reno10 Pro搭载动态光影屏:120Hz高刷
视点!不怕别人超越!“比亚迪魔方”储能系统发布:首搭刀片电池
环球新消息丨349元 OPPO Enco R2耳机发布:Hi-Fi级处理芯片
支付宝提醒“学生账户升级”骗局:没有学生/成人账户概念!
焦点快播:Spring Boot 我随手封装了一个万能的 Excel 导出工具,传什么都能导出!
火山引擎DataLeap联合DataFun发布《数据治理知识地图》_世界新消息
当前要闻:推荐一个AI导航网站 - 收录的都是热门AI工具
社区工作者感受垃圾分类处理全过程
北京西京医院杨博华_北京西京医院
64核CPU、显卡三连冠 AMD超算屠榜:唯一一台百亿亿次
国产SSD卷疯了!梵想S500 Pro 2TB只要409元 观天下
最轻薄潜望手机!OPPO Reno10 Pro+亮相
当前关注:搭载4.0L水平对置发动机 300万的保时捷中国开卖:但不能上路
淮北建投20亿元公司债将付息 利率6.30%
springboot~mybatis-plus的DynamicTableNameInnerInterceptor实现分表
用上3.0T直六发动机!马自达旗舰CX-90现身:今年内国产_天天看热讯
今日播报!Win11最新版发布:性能更好更丝滑
粤港澳大湾区首个京粤产业协作中心挂牌并落户广州黄埔 快播报
苹果WWDC23终极“剧透”:iOS 17登场 首款头显万众期待 天天精选
天天热点评!《原神》3.7版本正式上线!原神首个卡牌赛事登场
99包邮手慢无!匹克路威篮球鞋2折清仓(门店469元)
脾气真大!一特斯拉插队未遂现场报复:直接加速撞车 全球快看
甄子丹出演苹果广告:叶师傅 切他中路!|当前焦点
焦点播报:“五一”假期出行,伴随着哪些风险
全网最全的编程电子书大合集,超千本打包下载
求求你,不要再把ER图和数据库模型图搞混了好嘛?
【一步步开发AI运动小程序】六、人体骨骼图绘制|聚焦
全球观点:云图说丨初识商标注册服务
切辣椒手很辣该怎么办_切辣椒手辣要几个小时消失
焦点速讯:《街霸6》将迎合新一代玩家:隆、肯和春丽等老角色将被取代
今日精选:女孩减肥去世 体重仅24.8公斤!科普神经性厌食危害
“BOSS直聘崩了”登上热搜 公司回应:PC端异常 已紧急修复
电竞首次入赛!杭州亚运会《DOTA2》国家集训队名单出炉:共27人
今日关注:轻微交通事故APP快处 全国首批36城上线!附操作方法
微软重磅宣布!Windows 的“ AI 时刻”来了_环球新消息
【解决方法】SecureCRT远程工具无法show命令无法使用管道符完成中文过滤检索
Apache Hudi 在袋鼠云数据湖平台的设计与实践
CloudQuery v2.0.0 发布 | 新增数据保护、数据变更、连接管理等功能_环球观点
动态:JavaScript基础语法之 || 和 ?? 的踩坑记录
里夫斯:我在发声上做得不如詹眉 但高的篮球IQ会帮我提高领导力 世界微资讯
昆明国资委:“昆明银行口专家路演要点”和《昆明城投专家会议纪要》不实-焦点热门
微动态丨吉利也来“围攻”比亚迪 银河L7上市定档:1.5T插混能跑1300km
官网不停运!亚马逊中国回应7月关闭应用商店:不影响业务运营 天天快播报
迎来重磅更新!Win11文件管理器界面UI将整体重做
低价游太空梦破碎!维珍轨道破产 三大航空公司瓜分其资产|今日快看
双摄像头一览无余!萤石Y3000FVX极光人脸视频锁图赏|世界快资讯
【世界播资讯】现场直击|凯瑞特亮相CTT Expo 2023,热度飙升,实力圈粉
焦点讯息:sipp重放rtp数据测试FreeSWITCH
Algorithm_01--C#递归算法02 每日速看
HTML中的attribute 和 property
世界快资讯:Wi-Fi 6都没玩明白 怎么就惦记上Wi-Fi 7了?
今日关注:马斯克:已确定特斯拉接班人、自己有意外他将接管公司
速递!星巴克家享黑咖啡2.5元/杯大促 原价15元
世界微动态丨明天发布!小米Civi 3首发天玑8200-Ultra:能效、影像增强
千呼万唤始出来!微软官宣Win11任务栏不合并将回归
农发行广西区分行与东兰县签署战略合作协议
苹果MR或将推出 “果链”企业频受调研_环球快消息
骆仁童老师主讲《数字经济下电力业转型》课程 | 河北某地热电企业-2023年中高层管理人员培训班(二期)
80年代曾风靡全球 乐高为“吃豆人”游戏打造了一款街机 还能玩 焦点快看
世界热点评!新能源汽车高歌猛进 5月销量预计大增60% 渗透率超1/3
乌冬面里吃出活青蛙 日本连锁店鞠躬道歉:网友看完大呼恶心|世界热闻
越南打工人不加班逼急中国老板 不为钱放弃生活:全球各国每日工作时间一览-世界快讯
美国债务上限谈判未破僵局 避险美债再获追捧
为什么说人民币汇率不会大起大落-全球快播报
茶叶的故乡是哪里 茶的故乡是哪儿 天天报资讯
史诗级更新!特斯拉2023.12.9 OTA推送:强制单踏板成历史_天天短讯
Win10已死!微软发布Windows 11大更新:引入ChatGPT、升级巨大
《英雄联盟》衍生游戏!《聚点危机:英雄联盟外传》开售:GTX 460爽玩
全面实施国六B 这类汽车将禁止销售 会大幅降价吗?-今日播报
芦荟胶去红血丝效果好吗(芦荟胶对红血丝有效果吗)
焦点!5899元起 索尼新一代超广角变焦Vlog相机ZV-1 II发布
MarkDown的使用(一)
全球动态:宁波海达控股集团有限公司
苹果遭殃!逃税近千亿元-世界要闻
美团登陆香港的第一天 就把外卖价格干下来了! 环球新要闻
【天天时快讯】AMD Zen2架构复活!6nm重生、居然还有2核心2线程
主板卖不动!厂商憋出新招 当前热讯
这就是Intel显卡的意义!Arc A750限量版199美元史低价达成 天天热文
全球热点评!金钱树一次浇多少水_金钱树多久浇一次水
野生海参功效与作用_野生海参
丹丹看天气丨申城明天短时降温 后天重启入夏冲刺
焦点要闻:银行审核房贷一般几天 官方信息这样显示的
小清河6月底全线复航 可实现三种方式运输
审批时限缩短50%!云南省首个外国人才“一站式服务”专区启用
RTX 3070完全不是RTX 4060的对手!差距高下立判 天天速讯