【发布时间】:2019-12-22 11:26:56
【问题描述】:
当我使用mybatis在mysql的一个表中插入100000条记录时, 1. 在windows(我的电脑,16G+i7)中运行应用程序(springboot+mybatis)大约需要14s, 2. 但是我在centos7(product env, 4Core+8G ECS Server)上运行同一个应用需要1244s。
它们都连接到同一个mysql服务器(也在centos7上运行)。 centos7(产品环境)的网络连接更好。 CPU性能几乎相同(我已经测试过)。 应用简单,运行时只占用1G内存。
我的应用程序中的库版本: openjdk 版本“1.8.0_212”, 春季启动 2.1.6 , spring-boot-starter-tomcat-2.1.6.RELEASE.jar , spring-jdbc-5.0.7.RELEASE.jar , 德鲁伊-1.1.19.jar , mybatis-3.5.2.jar , mybatis-spring-2.0.2.jar , mybatis-spring-boot-starter-2.1.0.jar , mybatis-spring-boot-autoconfigure-2.1.0.jar , mysql-connector-java-5.1.38.jar ,
有人知道原因吗? 提前致谢。
================================
Foreach 插入(max_allowed_packet 已设置为 200M):
<insert id="insertBatch" parameterType="java.util.List" useGeneratedKeys="false">
insert into table_product
(id,
code,
status,
type,
create_time,
update_time)
values
<foreach collection="products" item="product" index="index" separator=",">
(#{product.id},
#{product.code},
#{product.status},
#{product.type},
#{product.createTime},
#{product.updateTime})
</foreach>
</insert>
===================================
按 ExecutorType.BATCH 插入:
public void batchInsert(List<Product> products){
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
BatchTableDao batchTableDao = session.getMapper(BatchTableDao.class);
try {
int i=0;
for (Product product : products) {
batchTableDao.insert(product);
if (i % 1000 == 0 || i == products.size()-1) {
session.flushStatements();
session.clearCache();
}
i++;
}
session.commit();
} catch (Exception e) {
Log.warn("error : "+e.getMessage());
} finally{
session.close();
}
}
====================================
在 windows 10 中,使用 'foreach' 插入 100000 行大约需要 14 秒。 并且使用'ExecutorType.BATCH'插入100000行大约需要2500s,接受速度太慢了。
【问题讨论】:
-
'Why' 对于其他人来说是一个很难回答的问题,但一般来说,多行插入在处理多行时并不适合。您应该考虑切换到批量插入。请参阅此answer 和链接的示例代码。
-
但是我发现使用 ExecutorType.BATCH 插入很多行真的很慢。它比使用“foreach”的方式慢了大约 100 倍。我已经附加了代码。谢谢。
-
这似乎不对。如果你可以在 GitHub 或类似的地方分享这个项目,我有空的时候会去看看。如果项目比较大,最好创建一个像these这样的小型单表项目。
-
这是我的简化代码。 batch 。谢谢。
-
我刚刚发送了一个 PR。更改是 (1) 将
rewriteBatchedStatements=true添加到 JDBC URL (2) 将批处理语句执行放在单个会话中。
标签: mysql spring-boot mybatis druid