社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
Mybatis与JDBC批量插入MySQL数据库性能测试
Author:boonya
Date:2017-04-13
系统中需要批量生成单据数据到数据库表,所以采用批量插入数据库的方式。由于系统中ORM操作集成使用的是Mybatis来完成的。
在Mybatis中操作一般使用批量插入的方式如下:
<insert id="insertBatch" parameterType="java.util.List" >
insert into userinfo (uid, uname, uphone, uaddress)
values
<foreach collection="list" item="item"index="index" separator=",">
(#{item.uid,jdbcType=INTEGER},
#{item.uname,jdbcType=VARCHAR},
#{item.uphone,jdbcType=VARCHAR},
#{item.uaddress,jdbcType=VARCHAR}
)
</foreach>
</insert>
在实际生产中发现,这样调用的效率并不高,于是我们迫切地需要寻找一种处理批量插入性能较高的方式——回归原生数据库JDBC操作。我们要分析Mybatis和JDBC的插入性能,来决策适合我们生产系统的批量插入方式。
参考资料中有一篇文章是对Spring Mybatis和Spring JDBC插入效率的测试,由于测试的数据量不多不予置评。
测试10组数据:
时间(ms) |
923 |
412 |
426 |
408 |
405 |
353 |
365 |
344 |
316 |
493 |
测试10组数据:
时间(ms) |
11031 |
3340 |
3571 |
2327 |
7273 |
1353 |
2676 |
1249 |
1245 |
1155 |
测试10组数据:
时间(ms) |
6070 |
5565 |
5731 |
5400 |
5830 |
5543 |
5469 |
5697 |
5528 |
5399 |
测试10组数据:
时间(ms) |
13383 |
12672 |
13030 |
13484 |
13841 |
12952 |
13331 |
13275 |
13000 |
13236 |
测试10组数据:
时间(ms) |
25312 |
24702 |
27065 |
25921 |
25156 |
24686 |
25314 |
33947 |
25304 |
25853 |
测试10组数据:
时间(ms) |
42148 |
39209 |
38548 |
40109 |
37820 |
37728 |
38178 |
38481 |
38157 |
39032 |
测试10组数据:
时间(ms) |
98250 |
88585 |
87438 |
89547 |
88427 |
89522 |
83261 |
80842 |
87163 |
84804 |
测试10组数据:
时间(ms) |
145481 |
146618 |
147098 |
145578 |
144947 |
145614 |
142014 |
142315 |
141984 |
143625 |
-- DELETE FROMprocess_spend_time_result WHEREpmethod='mybatis';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=1000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=2000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=4000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=6000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=8000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=15000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=20000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=1000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=2000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=4000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=6000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=8000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=15000 AND p.pmethod='mybatis';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=20000 AND p.pmethod='mybatis';
数据4舍5入保留3位小数
测试样例 | AVG(s) |
1K | 0.445 |
2K | 3.522 |
4K | 5.623 |
6K | 13.221 |
8K | 26.326 |
10K | 38.941 |
15K | 87.784 |
20K | 144.527 |
处理10000条耗时:34292ms
Windows下需要修改MySQL的my.ini文件加入如下配置内容:
max_allowed_packet=500M
Linux下是在/my.cnf修改添加如上内容。
也可以直接这样设置:
SET GLOBAL max_allowed_packet=1073741824;
但MySQL重启后就不起作用了。
在通过多线程并发处理的时,很容易导致数据库表锁表,使得后续的操作无法进行。
对象超出GC对象回收阀值,导致程序中断。
测试10组数据:
普通插入(ms) | 普通+事务(ms) | 普通批量(ms) | 批量+事务(MS) |
28489 | 801 | 31287 | 3494 |
30536 | 3042 | 35547 | 1899 |
25571 | 2041 | 31022 | 3501 |
27954 | 2733 | 28927 | 2547 |
29620 | 1261 | 34408 | 1449 |
27125 | 819 | 29318 | 923 |
28993 | 1079 | 31099 | 939 |
27594 | 2547 | 33504 | 3410 |
27967 | 781 | 31646 | 3587 |
33145 | 1293 | 37030 | 1912 |
测试10组数据:
普通插入(ms) | 普通+事务(ms) | 普通批量(ms) | 批量+事务(MS) |
131427 | 11568 | 168623 | 6926 |
132271 | 19313 | 231526 | 9915 |
192176 | 5238 | 227724 | 10978 |
185640 | 18955 | 227497 | 41959 |
211777 | 11238 | 184970 | 9461 |
208446 | 5019 | 263636 | 23394 |
253351 | 14265 | 227391 | 24870 |
225268 | 17009 | 229871 | 5583 |
163739 | 9719 | 230719 | 16657 |
215033 | 15802 | 238018 | 5330 |
测试10组数据:
普通插入(ms) | 普通+事务(ms) | 普通批量(ms) | 批量+事务(MS) |
308773 | 21389 | 360510 | 16432 |
352773 | 23487 | 372343 | 25545 |
378805 | 24034 | 368416 | 12507 |
384189 | 30119 | 392974 | 23742 |
369975 | 30651 | 378634 | 26180 |
368659 | 11902 | 416932 | 21321 |
388453 | 12644 | 411571 | 18138 |
391155 | 11287 | 396363 | 11678 |
368055 | 30987 | 399078 | 12212 |
363375 | 22576 | 361478 | 18544 |
测试10组数据:
普通插入(ms) | 普通+事务(ms) | 普通批量(ms) | 批量+事务(MS) |
942067 | 51343 | 990800 | 70103 |
1070688 | 28737 | 1051132 | 35536 |
1002076 | 38065 | 1222409 | 89644 |
1073114 | 57050 | 1312620 | 82354 |
960697 | 51733 | 1338932 | 33428 |
1025890 | 37666 | 1273338 | 76934 |
1017361 | 50916 | 1115627 | 92790 |
1077821 | 78650 | 1175512 | 52427 |
1038000 | 23290 | 1247797 | 91801 |
1200532 | 75494 | 1262051 | 72087 |
测试10组数据:
普通插入(ms) | 普通+事务(ms) | 普通批量(ms) | 批量+事务(MS) |
1914920 | 166575 | 2059826 | 146472 |
2111596 | 62807 | 1897888 | 125075 |
2174029 | 147265 | 1891542 | 166921 |
1948838 | 61284 | 2129791 | 93167 |
1909861 | 167575 | 1856811 | 56286 |
1990816 | 141381 | 1980060 | 148012 |
1896793 | 48087 | 2065937 | 56832 |
2130856 | 174388 | 2019914 | 113289 |
2073636 | 117462 | 2045715 | 102792 |
1966828 | 141319 | 1857867 | 116854 |
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 and p.pmethod='batchInsert';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 and p.pmethod='batchInsert2';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 and p.pmethod='batchInsertWithTransaction';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=10000 and p.pmethod='batchInsertWithTransaction2';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 and p.pmethod='batchInsert';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 and p.pmethod='batchInsert2';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 and p.pmethod='batchInsertWithTransaction';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=50000 and p.pmethod='batchInsertWithTransaction2';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 and p.pmethod='batchInsert';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 and p.pmethod='batchInsert2';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 and p.pmethod='batchInsertWithTransaction';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=100000 and p.pmethod='batchInsertWithTransaction2';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 and p.pmethod='batchInsert';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 and p.pmethod='batchInsert2';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 and p.pmethod='batchInsertWithTransaction';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=250000 and p.pmethod='batchInsertWithTransaction2';
SELECTAVG(p.ptime) FROM process_spend_time_resultp WHEREp.plimit=500000 andp.pmethod='batchInsert';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=500000 and p.pmethod='batchInsert2';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=500000 and p.pmethod='batchInsertWithTransaction';
SELECTAVG(p.ptime) FROMprocess_spend_time_result p WHERE p.plimit=500000 and p.pmethod='batchInsertWithTransaction2';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 and p.pmethod='batchInsert';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 and p.pmethod='batchInsert2';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 and p.pmethod='batchInsertWithTransaction';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=10000 and p.pmethod='batchInsertWithTransaction2';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=50000 and p.pmethod='batchInsert';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=50000 and p.pmethod='batchInsert2';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=50000 and p.pmethod='batchInsertWithTransaction';
SELECTAVG(p.ptime)/1000 FROM process_spend_time_resultp WHEREp.plimit=50000 andp.pmethod='batchInsertWithTransaction2';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p WHERE p.plimit=100000 and p.pmethod='batchInsert';
SELECTAVG(p.ptime)/1000 FROMprocess_spend_time_result p
原文链接:https://blog.csdn.net/boonya/article/details/70157820
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!