总结
- 
Mybatis内置的 ExecutorType有3种,默认的是simple单句模式,该模式下它为每个语句的执行创建一个新的预处理语句,单句提交sql;batch模式重复使用已经预处理的语句,并且批量执行所有语句,大批量模式下性能更优。- 请注意batch模式在Insert操作时事务没有提交之前,是没有办法获取到自增的id,所以请根据业务情况使用。
- 使用simple模式提交10000条数据,时间为19s,batch模式为6s ,大致情况如此,优化的具体还要看提交的语句情况。
 
- 请注意
- 
如果需要使用 foreach来优化数据插入的话,需要将每次插入的记录控制在 10-100 左右是比较快的,建议每次100来分割数据,也就是分而治之思想。
普通插入
默认的插入方式是遍历insert语句,单条执行,效率肯定低下,如果成堆插入,更是性能有问题。
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
INSERT INTO `table1` (`field1`, `field2`) VALUES ("data1", "data2");
foreach 优化插入
如果要优化插入速度时,可以将许多小型操作组合到一个大型操作中。理想情况下,这样可以在单个连接中一次性发送许多新行的数据,并将所有索引更新和一致性检查延迟到最后才进行。
<insert id="batchInsert" parameterType="java.util.List">
    insert into table1 (field1, field2) values
    <foreach collection="list" item="t" index="index" separator=","> 
        (#{t.field1}, #{t.field2})
    </foreach>
</insert>
翻译成sql语句也就是
INSERT INTO `table1` (`field1`, `field2`) 
VALUES ("data1", "data2"),
("data1", "data2"),
("data1", "data2"),
("data1", "data2"),
("data1", "data2");
foreach 遇到数量大,性能瓶颈
项目实践发现,当表的列数较多(超过20),以及一次性插入的行数较多(上万条)时,插入性能非常差,通常需要20分钟以上
这个时候就需要观察曲线了,10-100个来讲是很快的,当然也要根据项目请来看,总之建议100个就ok了,不要太高。
 
 executeBatch方法
批量执行的一种方式,使用PreparedStatement预编译进行优化。
int insertNum = 100;
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/xxx?useUnicode=true&characterEncoding=UTF-8&useServerPrepStmts=false&rewriteBatchedStatements=true","root","root123");
connection.setAutoCommit(false);
PreparedStatement ps = connection.prepareStatement(
        "insert into table1(field1) values(?)");
for (int i = 0; i < insertNum; i++) {
    ps.setString(1,"大狼狗"+insertNum);
    ps.addBatch();
}
ps.executeBatch();
connection.commit();
connection.close();
开启ExecutorType.BATCH模式
简单的讲就是openSession的时候带上参数ExecutorType.BATCH,可以几乎无损优化你的代码性能。
SqlSession session = sessionFactory.openSession(ExecutorType.BATCH);
for (Model model : list) {
    session.insert("insertStatement", model);
}
session.flushStatements();
BatchInsert模式
也是官方针对批量数据插入优化的方法之一
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
    TableMapper mapper = session.getMapper(TableMapper.class);
    //自定义你的方法来获取需要插入的数据
    List<TableRecord> records = getRecordsToInsert();
 	//BatchInsert
    BatchInsert<TableRecord> batchInsert = insert(records)
            .into(table)
            .map(id).toProperty("id")
            .map(field1).toProperty("field1")
            .map(field2).toProperty("field2")
            .build()
            .render(RenderingStrategy.MYBATIS3);
    batchInsert.insertStatements().stream().forEach(mapper::insert);
    session.commit();
} finally {
    session.close();
}
 
                    版权声明:程序员胖胖胖虎阿 发表于 2022年9月13日 下午6:48。
转载请注明:mybatis批量插入优化(ExecutorType.BATCH/BatchInsert/executeBatch) | 胖虎的工具箱-编程导航
                    
            转载请注明:mybatis批量插入优化(ExecutorType.BATCH/BatchInsert/executeBatch) | 胖虎的工具箱-编程导航
相关文章
暂无评论...
 
                             
                         
                            
