Mysql:批量插入数据优化

在一些中大型或者特殊业务项目,需要在极短时间产生大量数据。而平时最常见的两种插入方式是嵌套for单条插入和一次性批量插入。

for单条插入实例:

Java代码:

for(Product product : productList){
	productMapper.insert(product);
}

mapper.xml:

<insert id="insert useGeneratedKeys="true" keyProperty="id">
	insert into md_product ....
</insert>

此方式及其不推荐,不管你当前项目数据量生产量如何都不建议这样写代码。就像载货,为啥不装近满而要1件1件货来回运?

一次性批量插入

Java代码:

orderLogMapper.insertBatch(orderLogList);

mapper.xml:

    <insert id="insertBatch">
        insert into orde_log
        (
        order_id,
        content,
        operating_time,
        operator,
        origin_order_code,
        platform_order_code,
        log_type
        )
        values
        <foreach collection="ccSaleOrderLogList" item="item" index="index" separator="," >
            (
            #{item.orderId},
            #{item.content,jdbcType=VARCHAR},
            #{item.operatingTime,jdbcType=TIMESTAMP},
            #{item.operator,jdbcType=BIGINT},
            #{item.originOrderCode,jdbcType=VARCHAR},
            #{item.platformOrderCode,jdbcType=VARCHAR},
            #{item.logType,jdbcType=TINYINT}
            )
        </foreach>
    </insert>

此方式在效率上比第1种方式提升很多。但有一个小问题是数据量太多时,拼接的SQL会很长很容易出现插入失败,且效率的提升幅度不会很大

分片批量插入

分片批量插入是推荐使用的插入方式。比如50000条数据,可以拆分成5次,每次10000条数据进行批量插入。mapper.xml的代码和批量插入一模一样,不一样是Java代码,如下:
Java代码:

List<UserDetails> userListTotal = new ArrayList<>();//全部数据
            List<List<UserDetails>> partitionUserList = ListUtils.partition(userListTotal, 10000);//将数据进行分片,参数二为分片长度
            partitionUserList.parallelStream().forEach(list -> userMapper.insertBatch(list));
posted @ 2022-09-15 10:47  爱编程DE文兄  阅读(305)  评论(0编辑  收藏  举报