精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

MyBatis批量插入數(shù)據(jù)你還在用foreach?你們的服務(wù)器沒崩?

開發(fā) 后端
近日,項(xiàng)目中有一個(gè)耗時(shí)較長(zhǎng)的Job存在CPU占用過高的問題,經(jīng)排查發(fā)現(xiàn),主要時(shí)間消耗在往MyBatis中批量插入數(shù)據(jù)。

 [[435918]]

近日,項(xiàng)目中有一個(gè)耗時(shí)較長(zhǎng)的Job存在CPU占用過高的問題,經(jīng)排查發(fā)現(xiàn),主要時(shí)間消耗在往MyBatis中批量插入數(shù)據(jù)。mapper configuration是用foreach循環(huán)做的,差不多是這樣。(由于項(xiàng)目保密,以下代碼均為自己手寫的demo代碼) 

  1. <insert id="batchInsert" parameterType="java.util.List">  
  2.     insert into USER (id, name) values  
  3.     <foreach collection="list" item="model" index="index" separator=",">   
  4.         (#{model.id}, #{model.name})  
  5.     </foreach>  
  6. </insert> 

這個(gè)方法提升批量插入速度的原理是,將傳統(tǒng)的: 

  1. INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");  
  2. INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");  
  3. INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");  
  4. INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");  
  5. INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2"); 

轉(zhuǎn)化為: 

  1. INSERT INTO `table1` (`field1`, `field2`)   
  2. VALUES ("data1", "data2"),  
  3. ("data1", "data2"),  
  4. ("data1", "data2"),  
  5. ("data1", "data2"),  
  6. ("data1", "data2");  

在MySql Docs中也提到過這個(gè)trick,如果要優(yōu)化插入速度時(shí),可以將許多小型操作組合到一個(gè)大型操作中。理想情況下,這樣可以在單個(gè)連接中一次性發(fā)送許多新行的數(shù)據(jù),并將所有索引更新和一致性檢查延遲到最后才進(jìn)行。

乍看上去這個(gè)foreach沒有問題,但是經(jīng)過項(xiàng)目實(shí)踐發(fā)現(xiàn),當(dāng)表的列數(shù)較多(20+),以及一次性插入的行數(shù)較多(5000+)時(shí),整個(gè)插入的耗時(shí)十分漫長(zhǎng),達(dá)到了14分鐘,這是不能忍的。在資料中也提到了一句話:

Of course don't combine ALL of them, if the amount is HUGE. Say you have 1000 rows you need to insert, then don't do it one at a time. You shouldn't equally try to have all 1000 rows in a single query. Instead break it into smaller sizes.

它強(qiáng)調(diào),當(dāng)插入數(shù)量很多時(shí),不能一次性全放在一條語句里。可是為什么不能放在同一條語句里呢?這條語句為什么會(huì)耗時(shí)這么久呢?我查閱了資料發(fā)現(xiàn):

Insert inside Mybatis foreach is not batch, this is a single (could become giant) SQL statement and that brings drawbacks:

  •  some database such as Oracle here does not support.
  •  in relevant cases: there will be a large number of records to insert and the database configured limit (by default around 2000 parameters per statement) will be hit, and eventually possibly DB stack error if the statement itself become too large.

Iteration over the collection must not be done in the mybatis XML. Just execute a simple Insertstatement in a Java Foreach loop. The most important thing is the session Executor type. 

  1. SqlSession session = sessionFactory.openSession(ExecutorType.BATCH);  
  2. for (Model model : list) {  
  3.     session.insert("insertStatement", model);  
  4.  
  5. session.flushStatements(); 

Unlike default ExecutorType.SIMPLE, the statement will be prepared once and executed for each record to insert.

從資料中可知,默認(rèn)執(zhí)行器類型為Simple,會(huì)為每個(gè)語句創(chuàng)建一個(gè)新的預(yù)處理語句,也就是創(chuàng)建一個(gè)PreparedStatement對(duì)象。在我們的項(xiàng)目中,會(huì)不停地使用批量插入這個(gè)方法,而因?yàn)镸yBatis對(duì)于含有<foreach>的語句,無法采用緩存,那么在每次調(diào)用方法時(shí),都會(huì)重新解析sql語句。

Internally, it still generates the same single insert statement with many placeholders as the JDBC code above.

MyBatis has an ability to cache PreparedStatement, but this statement cannot be cached because it contains <foreach /> element and the statement varies depending on the parameters. As a result, MyBatis has to 1) evaluate the foreach part and 2) parse the statement string to build parameter mapping [1] on every execution of this statement.

And these steps are relatively costly process when the statement string is big and contains many placeholders.

[1] simply put, it is a mapping between placeholders and the parameters.

從上述資料可知,耗時(shí)就耗在,由于我foreach后有5000+個(gè)values,所以這個(gè)PreparedStatement特別長(zhǎng),包含了很多占位符,對(duì)于占位符和參數(shù)的映射尤其耗時(shí)。并且,查閱相關(guān)資料可知,values的增長(zhǎng)與所需的解析時(shí)間,是呈指數(shù)型增長(zhǎng)的。

所以,如果非要使用 foreach 的方式來進(jìn)行批量插入的話,可以考慮減少一條 insert 語句中 values 的個(gè)數(shù),最好能達(dá)到上面曲線的最底部的值,使速度最快。一般按經(jīng)驗(yàn)來說,一次性插20~50行數(shù)量是比較合適的,時(shí)間消耗也能接受。

重點(diǎn)來了。上面講的是,如果非要用<foreach>的方式來插入,可以提升性能的方式。而實(shí)際上,MyBatis文檔中寫批量插入的時(shí)候,是推薦使用另外一種方法。(可以看 http://www.mybatis.org/mybatis-dynamic-sql/docs/insert.html 中 Batch Insert Support 標(biāo)題里的內(nèi)容) 

  1. SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);  
  2. try {  
  3.     SimpleTableMapper mapper = session.getMapper(SimpleTableMapper.class);  
  4.     List<SimpleTableRecord> records = getRecordsToInsert(); // not shown  
  5.     BatchInsert<SimpleTableRecord> batchInsert = insert(records)  
  6.             .into(simpleTable)  
  7.             .map(id).toProperty("id")  
  8.             .map(firstName).toProperty("firstName")  
  9.             .map(lastName).toProperty("lastName")  
  10.             .map(birthDate).toProperty("birthDate")  
  11.             .map(employed).toProperty("employed")  
  12.             .map(occupation).toProperty("occupation")  
  13.             .build()  
  14.             .render(RenderingStrategy.MYBATIS3);  
  15.     batchInsert.insertStatements().stream().forEach(mapper::insert);  
  16.     session.commit();  
  17. } finally {  
  18.     session.close();  

即基本思想是將 MyBatis session 的 executor type 設(shè)為 Batch ,然后多次執(zhí)行插入語句。就類似于JDBC的下面語句一樣。 

  1. Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useServerPrepStmts=false&rewriteBatchedStatements=true","root","root"); 
  2. connection.setAutoCommit(false);  
  3. PreparedStatement ps = connection.prepareStatement(  
  4.         "insert into tb_user (name) values(?)");  
  5. for (int i = 0; i < stuNum; i++) {  
  6.     ps.setString(1,name);  
  7.     ps.addBatch();  
  8.  
  9. ps.executeBatch();  
  10. connection.commit();  
  11. connection.close(); 

經(jīng)過試驗(yàn),使用了 ExecutorType.BATCH 的插入方式,性能顯著提升,不到 2s 便能全部插入完成。

總結(jié)一下,如果MyBatis需要進(jìn)行批量插入,推薦使用 ExecutorType.BATCH 的插入方式,如果非要使用 <foreach>的插入的話,需要將每次插入的記錄控制在 20~50 左右。 

 

責(zé)任編輯:龐桂玉 來源: java版web項(xiàng)目
相關(guān)推薦

2020-02-21 14:15:40

SimpleDateFJava多線程

2022-09-23 09:44:17

MyBatisforeach

2024-03-26 10:30:37

Mybatis擴(kuò)展庫(kù)API

2015-07-09 11:32:26

AWSIaaS云計(jì)算

2012-07-19 10:03:32

2024-07-10 10:08:36

項(xiàng)目多表關(guān)聯(lián)哈希

2024-11-12 16:28:34

2021-09-27 07:56:41

MyBatis Plu數(shù)據(jù)庫(kù)批量插入

2023-08-30 09:16:38

PandasPython

2017-02-27 13:22:29

戴爾

2022-09-29 10:06:56

SQLMySQL服務(wù)端

2021-10-09 06:59:36

技術(shù)MyBatis數(shù)據(jù)

2020-03-04 14:05:35

戴爾

2025-09-08 04:00:00

2025-04-02 08:47:23

DOM文檔結(jié)構(gòu)API

2025-07-29 08:05:37

2023-12-04 09:14:00

數(shù)據(jù)庫(kù)MySQL

2023-01-05 07:55:59

Zookeeper服務(wù)注冊(cè)

2023-12-30 20:04:51

MyBatis框架數(shù)據(jù)

2017-02-13 12:20:13

大數(shù)據(jù)備份技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

国产偷人爽久久久久久老妇app| 在线观看国产一级片| 日韩一级片免费在线观看| 99精品国产在热久久婷婷| 精品香蕉在线观看视频一| 国产自偷自偷免费一区| 成人在线app| 成人精品一区二区三区四区 | 一色道久久88加勒比一| 欧美亚洲人成在线| 偷偷要91色婷婷| 伊人av成人| 五十路在线视频| 久久国内精品自在自线400部| 久久久久久久91| 天天舔天天操天天干| 1204国产成人精品视频| 欧美性大战xxxxx久久久| 日韩成人三级视频| 老司机在线永久免费观看| av色综合久久天堂av综合| 国产免费一区二区三区香蕉精| 国产无遮挡aaa片爽爽| 日韩大片在线| 亚洲精品视频在线播放| 亚洲av综合色区无码另类小说| 欧美日韩精品免费观看视欧美高清免费大片| 亚洲麻豆国产自偷在线| 日韩福利在线| 免费在线一级视频| 成人av网在线| 91久久极品少妇xxxxⅹ软件| 亚洲一区精品在线观看| 久久免费黄色| 欧美一级高清免费播放| 精品无码人妻一区二区三区| 国产精品久久久久久久免费观看| 亚洲欧美精品中文字幕在线| 亚洲欧美日韩偷拍| 在线视频亚洲欧美中文| 欧美精品久久天天躁| 中文久久久久久| 日韩伦理三区| 色综合网色综合| 日本少妇高潮喷水视频| h片在线观看| 亚洲成在线观看| 免费cad大片在线观看| 含羞草www国产在线视频| 国产精品麻豆视频| 中文精品视频一区二区在线观看| 91福利在线视频| 国产日韩欧美精品在线| 日韩高清国产一区在线观看| 九色蝌蚪在线| 国产亚洲短视频| 日本精品二区| 成人在线免费观看| 中文字幕欧美国产| 一区二区免费在线观看| 久草中文在线| 亚洲激情成人在线| 免费人成在线观看视频播放| 丰满的护士2在线观看高清| 一区二区高清在线| 国产综合av在线| 精品91久久| 欧美日韩一区久久| 无码国产精品一区二区高潮| 69精品国产久热在线观看| 精品国产在天天线2019| 182在线视频| 猛男gaygay欧美视频| 一区二区av在线| 天天看天天摸天天操| 欧美福利专区| 欧美一区二区三区图| 黄色污污网站在线观看| 久久aⅴ国产欧美74aaa| 波多野结衣久草一区| 99久久人妻精品免费二区| 国产精品主播在线观看| 日韩精品在线播放| 日本免费www| 欧美1区3d| 欧美中文在线字幕| 一区二区三区黄色片| 风间由美性色一区二区三区 | 九一在线视频| 国产精品初高中害羞小美女文| 丰满人妻一区二区三区53号| 一二三四视频在线中文| 欧美精品日韩综合在线| 噜噜噜在线视频| 久久福利综合| 97精品视频在线观看| 中文字幕在线播| 国产一区 二区 三区一级| 久久精品午夜一区二区福利| 欧美另类极品| 疯狂蹂躏欧美一区二区精品| 亚洲黄色片免费| 午夜先锋成人动漫在线| 久久夜色精品国产欧美乱| 国产成人愉拍精品久久| 激情国产一区二区| 麻豆视频成人| 日韩另类在线| 欧美日韩免费视频| 日本道中文字幕| 亚洲精品成人无限看| 欧美一级成年大片在线观看| 国产麻豆免费观看| 国产性做久久久久久| 国产成人艳妇aa视频在线| 成人黄色毛片| 亚洲精品视频播放| 久久婷婷一区二区| 韩国精品在线观看| 亚州欧美一区三区三区在线 | 国产精品视频免费在线观看| 日本精品一二区| 亚洲同性同志一二三专区| 国产一区视频免费观看| 露出调教综合另类| 欧美高清视频在线播放| 国产一区二区自拍视频| 国产亚洲人成网站| 99在线精品免费视频| 日韩在线成人| 久久精品小视频| 在线观看日本中文字幕| 欧美亚韩一区| 91视频免费在线| 天堂аⅴ在线地址8| 色国产精品一区在线观看| 久久免费精品国产| 欧美午夜久久| av一区二区在线看| 国产成人无吗| 欧美一区二区三区电影| 欧美肥妇bbwbbw| 久久99精品久久久久久国产越南| 日韩影片在线播放| 影音成人av| 永久免费看mv网站入口亚洲| 亚洲天堂视频网站| 久久亚洲一区二区三区明星换脸| 极品美女扒开粉嫩小泬| 蜜桃久久久久| 69影院欧美专区视频| 污污视频在线免费看| 亚洲国产欧美日韩另类综合| 丰满人妻一区二区三区免费视频棣 | 91精品国产色综合久久不卡蜜臀| 久久噜噜色综合一区二区| 美女视频一区二区| 91手机视频在线| 久久丁香四色| 欧美激情精品久久久久久久变态 | 免费在线成人激情电影| 中文字幕av一区中文字幕天堂 | 一区二区精品在线| 国产精品一区二区三区av| 欧美成人免费在线观看| 亚洲大尺度视频| 欧美日韩国产综合新一区| 中国黄色a级片| 日本aⅴ亚洲精品中文乱码| 亚洲伊人婷婷| 一区二区在线免费播放| 88国产精品欧美一区二区三区| 日本福利片在线| 欧美在线观看视频一区二区| 欧美做爰啪啪xxxⅹ性| 风间由美性色一区二区三区| 国产超级av在线| 日韩电影二区| aaa级精品久久久国产片| 色偷偷色偷偷色偷偷在线视频| 亚洲免费视频一区二区| 91久久国语露脸精品国产高跟| 亚洲免费观看高清完整| 国模私拍在线观看| 免费成人小视频| 国产精品久久久久久久乖乖| 少妇精品久久久一区二区| 成人黄色av免费在线观看| 男女在线观看视频| 国产一区二区三区18| jizz中国少妇| 色婷婷久久一区二区三区麻豆| 日本 欧美 国产| av亚洲精华国产精华精| 男人添女人下面免费视频| 国产精品第十页| 日韩一二三区不卡在线视频| 91成人午夜| 国产精品高潮视频| 高清视频在线观看三级| 精品国产一区二区三区久久| 无码h黄肉3d动漫在线观看| 88在线观看91蜜桃国自产| 精品一区免费观看| 中文字幕一区免费在线观看| 日韩片在线观看| 国产一区二区三区观看| 精品免费国产一区二区| 国产精品大片| 欧美性视频在线播放| 精品在线观看入口| 国产一区免费在线| 白嫩亚洲一区二区三区| 国产精品电影网| 伊人成综合网站| 久久久久久久久爱| 黄色网址免费在线观看| 亚洲人成在线电影| 婷婷在线免费观看| 欧美一卡2卡三卡4卡5免费| 国产美女www| 日韩欧美a级成人黄色| 在线免费观看毛片| 伊人开心综合网| 日本精品在线免费观看| 欧美激情在线看| 国产中年熟女高潮大集合| 99视频一区二区三区| 国产欧美视频一区| 国产精品原创巨作av| 五月六月丁香婷婷| 久久99热国产| 天天干天天操天天玩| 免费一级欧美片在线观看| 91精品91久久久中77777老牛| 亚洲国产裸拍裸体视频在线观看乱了中文 | 国产成人中文字幕| 最近高清中文在线字幕在线观看1| 久久久久久中文字幕| 黄网站在线观| 欧美激情亚洲自拍| 黑人另类精品××××性爽| 欧美激情国产日韩精品一区18| 中文字幕有码在线视频| 九色91av视频| 国产美女情趣调教h一区二区| 欧美激情在线有限公司| 麻豆蜜桃在线| 国内精品久久久久久影视8| av中文字幕在线观看第一页| 久久久久国产精品免费网站| а_天堂中文在线| 97欧美精品一区二区三区| 蜜桃视频www网站在线观看| 81精品国产乱码久久久久久| 中日韩脚交footjobhd| 日韩av男人的天堂| 99精品国自产在线| 国产欧美va欧美va香蕉在线| 国产情侣一区在线| 国产精华一区二区三区| 国产精品男女| 免费在线成人av| 日韩av在线播放网址| 在线观看免费黄色片| 红桃视频国产精品| 日韩欧美精品在线观看视频| 免费在线视频一区| 欧美日韩一区二区区| 99re热这里只有精品视频| 日韩在线免费观看av| 国产精品第一页第二页第三页 | 色综合天天做天天爱| 最新中文字幕第一页| 91精品午夜视频| 天天摸天天碰天天爽天天弄| 亚洲网站在线看| 国精产品一区| 欧美一区视频在线| 日韩专区视频| 国产一区二区黄色| 精品日韩欧美一区| 日本男女交配视频| 日本最新不卡在线| 日本黄色大片在线观看| 久久日一线二线三线suv| 色哟哟一一国产精品| 午夜视黄欧洲亚洲| 怡红院成永久免费人全部视频| 日韩一卡二卡三卡四卡| 丝袜视频国产在线播放| 欧美在线播放高清精品| 国产女人爽到高潮a毛片| 亚洲成人av资源网| 中文字幕日本在线观看| 高清一区二区三区四区五区| av一区在线播放| 国产精品我不卡| 99精品国产一区二区三区| 丝袜人妻一区二区三区| 奇米影视7777精品一区二区| 亚洲啪av永久无码精品放毛片| 国产精品视频看| 日韩精品视频免费看| 911精品产国品一二三产区| 三区在线观看| 欧美高清自拍一区| 国产成人精品一区二区三区视频 | 国产欧美日韩影院| 日韩中文字幕在线不卡| 免播放器亚洲一区| 爱爱免费小视频| 亚洲国产一区二区三区| 国产裸体永久免费无遮挡| 亚洲欧洲在线看| 国产探花视频在线观看| 国产日韩欧美一二三区| 国产欧美日韩在线观看视频| 欧美视频免费看欧美视频| 国产一区二区三区综合| 1024手机在线观看你懂的| 精品成人av一区| 亚洲第一天堂在线观看| 北条麻妃一区二区三区中文字幕 | 怡红院在线播放| 成人免费黄色网| 清纯唯美综合亚洲| 亚洲中文字幕久久精品无码喷水 | 人与动物性xxxx| 在线观看日韩电影| 精品国产www| 亚洲女人天堂色在线7777| 超碰99在线| 国产精品乱码一区二区三区| 午夜日韩电影| 日本亚洲一区二区三区| 亚洲三级小视频| 一区二区久久精品66国产精品 | 日本动漫同人动漫在线观看| 亚洲xxxx18| 国产一区亚洲| 黄色av电影网站| 精品成人在线视频| 婷婷在线观看视频| 2019av中文字幕| 亚洲色图丝袜| 天天碰免费视频| 亚洲国产精品t66y| 亚洲天堂中文字幕在线| 日韩视频精品在线| 美女久久精品| 日韩 欧美 视频| av电影在线观看一区| 久久久久99精品成人片我成大片| 日韩av在线免费观看| 成人av三级| 亚洲高清视频一区| 国产精品99一区二区三| 热久久久久久久久| 一区二区在线免费| 天天操天天干天天干| 日韩美女在线观看一区| 久久一区二区三区电影| 日韩成人精品视频在线观看| 一区二区在线观看视频| 日本加勒比一区| 国产精品h片在线播放| 手机在线电影一区| 18深夜在线观看免费视频| 亚洲va韩国va欧美va| 免费在线稳定资源站| 国产日韩欧美中文| 精品二区久久| 国产美女永久免费无遮挡| 91精品综合久久久久久| 91豆花视频在线播放| 欧美视频观看一区| 国内外成人在线| 国产在线精品观看| 亚洲视频电影图片偷拍一区| 91九色成人| 亚洲中文字幕无码专区| 国产精品久久午夜| 成人乱码一区二区三区| 国产成人拍精品视频午夜网站| 91精品国产自产在线观看永久∴| youjizz.com日本| 欧美三级电影网站| 91www在线| 宅男av一区二区三区| k8久久久一区二区三区| 在线免费看毛片| 97人人模人人爽人人喊中文字| 精品国产一区二区三区四区| 国产精品99精品无码视亚| 日本福利一区二区| 国产精品—色呦呦| 这里只有精品66| 91美女福利视频| 精品人妻一区二区三区含羞草|