1、saveBatch批量插入等批量操作耗时特别长,对于上万条数据更是十几秒
- 答:先说解决方案:jdbc URL后追加参数 rewriteBatchedStatements=true,让多个insert/update/delete语句同一批次提交,而不是分开多次提交,除此之外,还需要自定义insert sql,不使用MP的saveXXX
2、原理
-
mysql jdbc driver发布文档,从3.1.13开始加入了该功能:https://dev.mysql.com/doc/relnotes/connector-j/5.1/en/news-3-1-13.html
-
添加了性能功能,重写批处理执行 Statement.executeBatch()(对于所有 DML 语句)和 PreparedStatement.executeBatch()(仅对于具有 VALUE 子句的 INSERT)。通过在 JDBC URL 中使用“rewriteBatchedStatements=true”来启用。(错误#18041)
-
doc文档:https://dev.mysql.com/doc/connectors/en/connector-j-connp-props-performance-extensions.html#cj-conn-prop_rewriteBatchedStatements
-
文档截图:
3、MP源码解析
- 如果不传每次批量提交,默认每1000提交一次
INSERT_ONE("insert", "插入一条数据(选择字段插入)", "<script>\nINSERT INTO %s %s VALUES %s\n</script>"),
public boolean saveBatch(Collection<T> entityList, int batchSize) {
String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
}
- 可以看到,MP其实是在循环里面逐个insert的,达到批次阈值,就刷到数据库