springboot+mybatis批量插入mysql,linux比windows慢很多。啥可能导致它?

Posted

技术标签:

【中文标题】springboot+mybatis批量插入mysql,linux比windows慢很多。啥可能导致它?【英文标题】:Batch Insert into mysql by springboot+mybatis, it is much slower in linux than in windows. What could have caused it?springboot+mybatis批量插入mysql,linux比windows慢很多。什么可能导致它? 【发布时间】: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_pa​​cket 已设置为 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) 将批处理语句执行放在单个会话中。 【参考方案1】:

首先,换成the official document指定的版本怎么样?而且我认为您需要更多地了解代码。

【讨论】:

我已经把版本改成官方要求了,问题还是一样。而且我也尝试过使用 ExecutorType.BATCH 进行批量插入,它真的很慢。谢谢。

以上是关于springboot+mybatis批量插入mysql,linux比windows慢很多。啥可能导致它?的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis 批量插入的 3 种方式!还有谁不会?

验证mybatis批量插入能否一次能插入1万条数据

springboot mybatis注解方式批量insert和使用in语句查询

MyBatis 批量插入的 3 种方式!还有谁不会?

mybatis批量插入批量删除

Java--MyBatis批量插入批量更新和批量删除