MySQL 批量插入数据 SQL优化
在实习工作中遇到一个场景,每次执行会获得上万条数据,需要将数据入库。
使用guava-11.0.2.jar包下的Lists类:
1、将包含10000条数据的list列表分割为1000条数据的十个list,然后循环遍历每次插入1000条数据。
2、并使用@Transactional注解开启事务,当所有的插入语句都执行完成之后再commit,这样做可以减少频繁创建事务所消耗的资源。
@Transactional public void insertData(List<String> list){ int splitSize = 1000;
List<List<String>> partition Lists.partition(list,splitSize);
for (List<String> split : partition)
{
dataMapper.insertData(split);
}
}
3、使用Mybatis的foreach标签生成sql语句。
<insert id="insertData" parameterType="java.util.List"> insert into table(id,b,c,d,e,f,g,h) values <foreach collection="list" item="item" separator=","> (#{id},#{b},#{c},#{d},#{e},#{f},#{g},#{h}) </foreach> </insert>
4、优化MySQL表结构,将id字段设置为int自增长,Mybatis的xml文件中的SQL语句中去掉id字段,由于是自增长所以不需要填写,并且提高了插入效率。
5、由于之前的主键id使用的是UUID,无序的UUID索引影响插入性能。
6、使用有序索引可提高插入效率,每次插入记录都在索引的最后面,索引的定位效率很高,并且对索引调整较小。如果插入的记录在索引中间,需要B+tree
进行分裂合并等处理,会消耗比较多计算资源,并且插入记录的索引定位效率会下降,数据量较大时会有频繁的磁盘操作。
<insert id="insertData" parameterType="java.util.List"> insert into table(b,c,d,e,f,g,h) values <foreach collection="list" item="item" separator=","> (#{b},#{c},#{d},#{e},#{f},#{g},#{h}) </foreach> </insert>