网站首页 > 数据库 / 正文
在使用MyBatis进行批量插入数据时,我们常用的方法是在使用insert语句进行批量插入,这种方式在数据量比较少的时候,插入较快,但是当数据量较大的时候,不仅耗时,而且占用的CPU资源比较高。今天我们来对比说明一下,并在最后给出优化的方案。
先设计一张MySQL数据库,用来存储批量插入的数据,以插入用户信息为例,本次表在设计时多设计一些字段,在插入时的差异凸显的更加明显。
接下来我以插入50000条数据为例,由浅入深,分别从循环单条插入、批量插入等进行对比分析。
1、循环单条插入
模拟生成用户的姓名、手机号、身份证号码这些信息,避免因相同数据造成的缓存误差,然后逐条插入数据库中。
随机生成用户姓名:
随机生成11位手机号码:
随机生成身份证号码:
逐条插入用户数据的实现方法(使用JUnit进行单元测试),需要了解JUnit进行单元测试,可以访问上一篇文章SpringBoot框架集成JUnit单元测试:
插入完毕,查看控制台总耗时,以及数据库的数据入库情况:
执行总共耗时1634240ms,也就是27分钟左右。
2、使用foreach批量插入
在同等条件下进行测试验证,还是自动生成用户信息,封装成list,然后一次性插入。
这种方式相对于第一种方式,进行了提升,原理就是将
转换为
此时我们去执行程序发现,程序报错
如果我们将批量插入的50000条数据改成10000条,发现1秒左右就执行结束了。
从上面可以看出,使用foreach进行批量插入,原理上就是让多条insert into插入语句变成一条插入语句,可以带来性能上的提升,但同时也带来了两个问题:
(1)当插入的数据较多时,相当于拼接的sql语句会特别的长,甚至超过sql语句的长度,一旦超出,就会抛出异常导致无法插入。
(2)当插入的数据较多时,也比较耗时,针对这点官方也做了说明,这里我们就不做详细的拓展,我们继续讨论怎么解决这个问题。这里贴一张官方的说明截图。
这句话要表达的意思就是,当插入数量很多时,不能一次性全放在一条语句里。
3、使用foreach配合分片批量插入
既然不能封装成一条SQL,那我们考虑有没有其他的方式,当然有,可以采用分片的方式。
主要原理就是将list集合按"指定长度"进行切分,返回新的List<List<类型>>集合。
可以看出,50000条数据,不到2秒钟就插入完成,大大提高了效率。
这里分片的目的有两个:
1、批量插入,拼接的SQL语句过长,sql语句会有限制;
2、分片后采用stream多线程并行插入可以提高效率;
此外,不管是mysql还是oracle数据库,都可以使用分片进行插入。
Tags:oracle insert into
猜你喜欢
- 2024-11-26 Oracle中JDBC处理PreparedStatement处理Char问题浅析
- 2024-11-26 基于Percona XtraBackup 实现全备&增量备份与恢复
- 2024-11-26 ORACLE 错误代码及解决办法
- 2024-11-26 了解 Oracle 中单引号与双引号的用法,一篇文章教会你!
- 2024-11-26 WINCC保存数据到Oracle
- 2024-11-26 分享一个神奇现象--插入数据提示表不存在但却能查到这个表?
- 2024-11-26 oracle: PLSQL概念,关系运算符,顺序结构,分支结构,循环结构
- 2024-11-26 一个空格引发的“惨案“
- 2024-11-26 mybatis+oracle实现批量添加
- 2024-11-26 详解mysql数据库另类实现merge into语法的两种方式