chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何調(diào)優(yōu)MyBatis 25倍性能

jf_ro2CN3Fa ? 來(lái)源:芋道源碼 ? 2023-05-30 09:56 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

來(lái)源:yes的練級(jí)攻略
  • 粗略的實(shí)驗(yàn)
  • 最后


最近在壓測(cè)一批接口,發(fā)現(xiàn)接口處理速度慢的有點(diǎn)超出預(yù)期,感覺很奇怪,后面定位發(fā)現(xiàn)是數(shù)據(jù)庫(kù)批量保存這塊很慢。

這個(gè)項(xiàng)目用的是 mybatis-plus,批量保存直接用的是 mybatis-plus 提供的 saveBatch。

我點(diǎn)進(jìn)去看了下源碼,感覺有點(diǎn)不太對(duì)勁:

2ad185ce-fe8a-11ed-90ce-dac502259ad0.png

我繼續(xù)追蹤了下,從這個(gè)代碼來(lái)看,確實(shí)是 for 循環(huán)一條一條執(zhí)行了 sqlSession.insert,下面的 consumer 執(zhí)行的就是上面的 sqlSession.insert:

2adaae10-fe8a-11ed-90ce-dac502259ad0.png

然后累計(jì)一定數(shù)量后,一批 flush。

從這點(diǎn)來(lái)看,這個(gè) saveBach 的性能肯定比直接一條一條 insert 快。

我直接進(jìn)行一個(gè)粗略的實(shí)驗(yàn),簡(jiǎn)單創(chuàng)建了一張表來(lái)對(duì)比一波!

粗略的實(shí)驗(yàn)

1000條數(shù)據(jù),一條一條插入

@Test
voidMybatisPlusSaveOne(){
SqlSessionsqlSession=sqlSessionFactory.openSession();
try{
StopWatchstopWatch=newStopWatch();
stopWatch.start("mybatisplussaveone");
for(inti=0;i1000;i++){
OpenTestopenTest=newOpenTest();
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();
}
}
2ae2c12c-fe8a-11ed-90ce-dac502259ad0.png

可以看到,執(zhí)行一批 1000 條數(shù)的批量保存,耗費(fèi)的時(shí)間是 121011 毫秒。

1000條數(shù)據(jù)用 mybatis-plus 自帶的 saveBatch 插入

@Test
voidMybatisPlusSaveBatch(){
SqlSessionsqlSession=sqlSessionFactory.openSession();
try{
ListopenTestList=newArrayList<>();
for(inti=0;i1000;i++){
OpenTestopenTest=newOpenTest();
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);
}
StopWatchstopWatch=newStopWatch();
stopWatch.start("mybatisplussavebatch");
//批量插入
openTestService.saveBatch(openTestList);
sqlSession.commit();
stopWatch.stop();
log.info("mybatis plus save batch:"+stopWatch.getTotalTimeMillis());
}finally{
sqlSession.close();
}
}
2ae81f1e-fe8a-11ed-90ce-dac502259ad0.png

耗費(fèi)的時(shí)間是 59927 毫秒,比一條一條插入快了一倍,從這點(diǎn)來(lái)看,效率還是可以的。

然后常見的還有一種利用拼接 sql 方式來(lái)實(shí)現(xiàn)批量插入,我們也來(lái)對(duì)比試試看性能如何。

1000條數(shù)據(jù)用手動(dòng)拼接 sql 方式插入

搞個(gè)手動(dòng)拼接:

2aef8592-fe8a-11ed-90ce-dac502259ad0.png來(lái)跑跑下性能如何:

@Test
voidMapperSaveBatch(){
SqlSessionsqlSession=sqlSessionFactory.openSession();
try{
ListopenTestList=newArrayList<>();
for(inti=0;i1000;i++){
OpenTestopenTest=newOpenTest();
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);
}
StopWatchstopWatch=newStopWatch();
stopWatch.start("mappersavebatch");
//手動(dòng)拼接批量插入
openTestMapper.saveBatch(openTestList);
sqlSession.commit();
stopWatch.stop();
log.info("mapper save batch:"+stopWatch.getTotalTimeMillis());
}finally{
sqlSession.close();
}
}
2af6df90-fe8a-11ed-90ce-dac502259ad0.png

耗時(shí)只有 2275 毫秒,性能比 mybatis-plus 自帶的 saveBatch 好了 26 倍!

這時(shí),我又突然回想起以前直接用 JDBC 批量保存的接口,那都到這份上了,順帶也跑跑看!

1000條數(shù)據(jù)用 JDBC executeBatch 插入

@Test
voidJDBCSaveBatch()throwsSQLException{
SqlSessionsqlSession=sqlSessionFactory.openSession();
Connectionconnection=sqlSession.getConnection();
connection.setAutoCommit(false);

Stringsql="insertintoopen_test(a,b,c,d,e,f,g,h,i,j,k)values(?,?,?,?,?,?,?,?,?,?,?)";
PreparedStatementstatement=connection.prepareStatement(sql);
try{
for(inti=0;i1000;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();
}
StopWatchstopWatch=newStopWatch();
stopWatch.start("JDBCsavebatch");
statement.executeBatch();
connection.commit();
stopWatch.stop();
log.info("JDBC save batch:"+stopWatch.getTotalTimeMillis());
}finally{
statement.close();
sqlSession.close();
}
}
2afea46e-fe8a-11ed-90ce-dac502259ad0.png

耗時(shí)是 55663 毫秒,所以 JDBC executeBatch 的性能跟 mybatis-plus 的 saveBatch 一樣(底層一樣)。

綜上所述,拼接 sql 的方式實(shí)現(xiàn)批量保存效率最佳。

但是我又不太甘心,總感覺應(yīng)該有什么別的法子,然后我就繼續(xù)跟著 mybatis-plus 的源碼 debug 了一下,跟到了 mysql 的驅(qū)動(dòng),突然發(fā)現(xiàn)有個(gè) if 里面的條件有點(diǎn)顯眼:

2b05fd7c-fe8a-11ed-90ce-dac502259ad0.png

就是這個(gè)叫 rewriteBatchedStatements 的玩意,從名字來(lái)看是要重寫批操作的 Statement,前面batchHasPlainStatements 已經(jīng)是 false,取反肯定是 true,所以只要這參數(shù)是 true 就會(huì)進(jìn)行一波操作。

我看了下默認(rèn)是 false。

2b0cc0b2-fe8a-11ed-90ce-dac502259ad0.png

同時(shí)我也上網(wǎng)查了下 rewriteBatchedStatements 參數(shù),好家伙,好像有用!我直接將 jdbcurl 加上了這個(gè)參數(shù):

2b13cef2-fe8a-11ed-90ce-dac502259ad0.png

然后繼續(xù)跑了下 mybatis-plus 自帶的 saveBatch,果然性能大大提高,跟拼接 SQL 差不多!

2b1b2bac-fe8a-11ed-90ce-dac502259ad0.png

順帶我也跑了下 JDBC 的 executeBatch ,果然也提高了。

2b21ec58-fe8a-11ed-90ce-dac502259ad0.png

然后我繼續(xù) debug ,來(lái)探探 rewriteBatchedStatements 究竟是怎么 rewrite 的!

如果這個(gè)參數(shù)是 true,則會(huì)執(zhí)行下面的方法且直接返回:

2b30f07c-fe8a-11ed-90ce-dac502259ad0.png

看下 executeBatchedInserts 究竟干了什么:

2b37bbfa-fe8a-11ed-90ce-dac502259ad0.png

看到上面我圈出來(lái)的代碼沒,好像已經(jīng)有點(diǎn)感覺了,繼續(xù)往下 debug。

果然!sql 語(yǔ)句被 rewrite了:

2b3e7e7c-fe8a-11ed-90ce-dac502259ad0.png

對(duì)插入而言,所謂的 rewrite 其實(shí)就是將一批插入拼接成 insert into xxx values (a),(b),(c)...這樣一條語(yǔ)句的形式然后執(zhí)行,這樣一來(lái)跟拼接 sql 的效果是一樣的。

那為什么默認(rèn)不給這個(gè)參數(shù)設(shè)置為 true 呢?

原來(lái)是這樣的:

  1. 如果批量語(yǔ)句中的某些語(yǔ)句失敗,則默認(rèn)重寫會(huì)導(dǎo)致所有語(yǔ)句都失敗。
  2. 批量語(yǔ)句的某些語(yǔ)句參數(shù)不一樣,則默認(rèn)重寫會(huì)使得查詢緩存未命中。

看起來(lái)影響不大,所以我給我的項(xiàng)目設(shè)置上了這個(gè)參數(shù)!

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

最后

稍微總結(jié)下我粗略的對(duì)比(雖然粗略,但實(shí)驗(yàn)結(jié)果符合原理層面的理解),如果你想更準(zhǔn)確地實(shí)驗(yàn),可以使用JMH,并且測(cè)試更多組數(shù)(如 5000,10000等)的情況。

批量保存方式 數(shù)據(jù)量(條) 耗時(shí)(ms)
單條循環(huán)插入 1000 121011
mybatis-plus saveBatch 1000 59927
mybatis-plus saveBatch(添加rewtire參數(shù)) 1000 2589
手動(dòng)拼接sql 1000 2275
jdbc executeBatch 1000 55663
jdbc executeBatch(添加rewtire參數(shù)) 1000 324

所以如果有使用 jdbc 的 Batch 性能方面的需求,要將 rewriteBatchedStatements 設(shè)置為 true,這樣能提高很多性能。

然后如果喜歡手動(dòng)拼接 sql 要注意一次拼接的數(shù)量,分批處理。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 源碼
    +關(guān)注

    關(guān)注

    8

    文章

    682

    瀏覽量

    31073
  • 接口處理
    +關(guān)注

    關(guān)注

    0

    文章

    3

    瀏覽量

    6495
  • mybatis
    +關(guān)注

    關(guān)注

    0

    文章

    64

    瀏覽量

    7077

原文標(biāo)題:調(diào)優(yōu) MyBatis 25 倍性能

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    實(shí)戰(zhàn)RK3568性能調(diào)優(yōu):如何利用迅為資料壓榨NPU潛能-在Android系統(tǒng)中使用NPU

    《實(shí)戰(zhàn)RK3568性能調(diào)優(yōu):如何利用迅為資料壓榨NPU潛能-在Android系統(tǒng)中使用NPU》
    的頭像 發(fā)表于 11-07 13:42 ?208次閱讀
    實(shí)戰(zhàn)RK3568<b class='flag-5'>性能</b><b class='flag-5'>調(diào)</b><b class='flag-5'>優(yōu)</b>:如何利用迅為資料壓榨NPU潛能-在Android系統(tǒng)中使用NPU

    天翼云基于開源歐拉的智能調(diào)優(yōu)實(shí)踐

    在數(shù)字經(jīng)濟(jì)加速滲透的當(dāng)下,操作系統(tǒng)作為底層基礎(chǔ)設(shè)施的核心,其穩(wěn)定性與適配性直接關(guān)系到行業(yè)數(shù)字化進(jìn)程。隨著CentOS停止維護(hù),國(guó)內(nèi)企業(yè)面臨操作系統(tǒng)遷移的緊迫需求,天翼云基于開源歐拉研發(fā)的CTyunOS,不僅成為這一遷移浪潮中的關(guān)鍵解決方案,更通過智能調(diào)優(yōu)實(shí)踐,為數(shù)字經(jīng)濟(jì)筑
    的頭像 發(fā)表于 10-17 11:04 ?452次閱讀

    1218 MHz、25 dB 增益 CATV 功率放大器 skyworksinc

    電子發(fā)燒友網(wǎng)為你提供()1218 MHz、25 dB 增益 CATV 功率放大器相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊(cè),更有1218 MHz、25 dB 增益 CATV 功率放大器的引腳圖、接線圖
    發(fā)表于 09-01 18:31
    1218 MHz、<b class='flag-5'>25</b> dB 增益 CATV <b class='flag-5'>倍</b>功率放大器 skyworksinc

    HarmonyOSAI編程智慧調(diào)優(yōu)

    DevEco Studio提供智慧調(diào)優(yōu)能力,支持通過自然語(yǔ)言交互,分析并解釋當(dāng)前實(shí)例或項(xiàng)目中存在的性能問題,幫助開發(fā)者快速定位影響性能的具體原因。該功能從DevEco Studio 6
    發(fā)表于 09-01 15:15

    Linux服務(wù)器性能調(diào)優(yōu)的核心技巧和實(shí)戰(zhàn)經(jīng)驗(yàn)

    如果你正在為這些問題頭疼,那么這篇文章就是為你準(zhǔn)備的!作為一名擁有10年經(jīng)驗(yàn)的運(yùn)維工程師,我將毫無(wú)保留地分享Linux服務(wù)器性能調(diào)優(yōu)的核心技巧和實(shí)戰(zhàn)經(jīng)驗(yàn)。
    的頭像 發(fā)表于 08-27 14:36 ?690次閱讀

    Linux性能監(jiān)控與調(diào)優(yōu)技巧

    作為一名在一線摸爬滾打多年的運(yùn)維工程師,我見過太多因?yàn)?b class='flag-5'>性能問題導(dǎo)致的線上故障。凌晨2點(diǎn)被告警電話吵醒,面對(duì)CPU飆升到100%、內(nèi)存不足、磁盤IO瓶頸等問題時(shí)的那種焦慮,相信每個(gè)運(yùn)維人都深有體會(huì)。
    的頭像 發(fā)表于 08-18 11:26 ?601次閱讀

    HarmonyOS AI輔助編程工具(CodeGenie)智慧調(diào)優(yōu)

    DevEco Studio提供智慧調(diào)優(yōu)能力,支持通過自然語(yǔ)言交互,分析并解釋當(dāng)前實(shí)例或項(xiàng)目中存在的性能問題,幫助開發(fā)者快速定位影響性能的具體原因。該功能從DevEco Studio 6
    發(fā)表于 08-14 11:12

    Linux網(wǎng)絡(luò)性能調(diào)優(yōu)方案

    在當(dāng)今高并發(fā)、大流量的互聯(lián)網(wǎng)環(huán)境下,網(wǎng)絡(luò)性能往往成為系統(tǒng)的瓶頸。作為一名資深運(yùn)維工程師,我在生產(chǎn)環(huán)境中遇到過無(wú)數(shù)次因?yàn)門CP/IP參數(shù)配置不當(dāng)導(dǎo)致的性能問題。今天分享一套完整的Linux網(wǎng)絡(luò)性能
    的頭像 發(fā)表于 08-06 18:01 ?939次閱讀

    Linux內(nèi)核參數(shù)調(diào)優(yōu)方案

    在高并發(fā)微服務(wù)環(huán)境中,網(wǎng)絡(luò)性能往往成為K8s集群的瓶頸。本文將深入探討如何通過精細(xì)化的Linux內(nèi)核參數(shù)調(diào)優(yōu),讓你的K8s節(jié)點(diǎn)網(wǎng)絡(luò)性能提升30%以上。
    的頭像 發(fā)表于 08-06 17:50 ?696次閱讀

    Linux系統(tǒng)性能調(diào)優(yōu)方案

    關(guān)鍵要點(diǎn)預(yù)覽:本文將深入解析Linux系統(tǒng)性能瓶頸的根本原因,提供可直接落地的調(diào)優(yōu)方案,讓你的系統(tǒng)性能提升30-50%!
    的頭像 發(fā)表于 08-06 17:49 ?559次閱讀

    MySQL配置調(diào)優(yōu)技巧

    上個(gè)月,我們公司的核心業(yè)務(wù)系統(tǒng)突然出現(xiàn)大面積超時(shí),用戶投訴電話不斷。經(jīng)過緊急排查,發(fā)現(xiàn)是MySQL服務(wù)器CPU飆升到99%,大量慢查詢堆積。通過一系列配置調(diào)優(yōu)和SQL優(yōu)化,最終在30分鐘內(nèi)恢復(fù)了服務(wù)。
    的頭像 發(fā)表于 07-31 10:27 ?386次閱讀

    Nginx在企業(yè)環(huán)境中的調(diào)優(yōu)策略

    Nginx作為現(xiàn)代互聯(lián)網(wǎng)架構(gòu)中最重要的Web服務(wù)器和反向代理服務(wù)器,其性能調(diào)優(yōu)對(duì)企業(yè)級(jí)應(yīng)用的穩(wěn)定性和效率至關(guān)重要。本指南將從運(yùn)維實(shí)踐角度出發(fā),詳細(xì)介紹Nginx在企業(yè)環(huán)境中的各種調(diào)
    的頭像 發(fā)表于 07-14 11:13 ?393次閱讀

    手把手教你如何調(diào)優(yōu)Linux網(wǎng)絡(luò)參數(shù)

    在高并發(fā)網(wǎng)絡(luò)服務(wù)場(chǎng)景中,Linux內(nèi)核的默認(rèn)網(wǎng)絡(luò)參數(shù)往往無(wú)法滿足需求,導(dǎo)致性能瓶頸、連接超時(shí)甚至服務(wù)崩潰。本文基于真實(shí)案例分析,從參數(shù)解讀、問題診斷到優(yōu)化實(shí)踐,手把手教你如何調(diào)優(yōu)Linux網(wǎng)絡(luò)參數(shù),支撐百萬(wàn)級(jí)并發(fā)連接。
    的頭像 發(fā)表于 05-29 09:21 ?632次閱讀

    一鍵對(duì)焦+一鍵調(diào)平,測(cè)量效率提升7 | 優(yōu)可測(cè)全新旗艦白光干涉儀發(fā)布

    測(cè)量精度小于1納米,性能進(jìn)入全球一梯隊(duì),優(yōu)可測(cè)旗艦白光干涉儀發(fā)布
    的頭像 發(fā)表于 03-27 11:03 ?968次閱讀
    一鍵對(duì)焦+一鍵<b class='flag-5'>調(diào)</b>平,測(cè)量效率提升7<b class='flag-5'>倍</b> | <b class='flag-5'>優(yōu)</b>可測(cè)全新旗艦白光干涉儀發(fā)布

    xgboost超參數(shù)調(diào)優(yōu)技巧 xgboost在圖像分類中的應(yīng)用

    的成績(jī)。然而,XGBoost模型涉及眾多超參數(shù),這些參數(shù)的組合和調(diào)優(yōu)對(duì)于模型性能至關(guān)重要。以下是一些XGBoost超參數(shù)調(diào)優(yōu)的技巧: 理解主
    的頭像 發(fā)表于 01-31 15:16 ?2126次閱讀