【问题标题】:Very slow activation of Spring Data JPA saveAll / save methods with Spring boot 2 and mysql使用 Spring Boot 2 和 mysql 激活 Spring Data JPA saveAll / save 方法非常慢
【发布时间】:2019-01-14 14:12:02
【问题描述】:

我的 Spring boot 应用正在使用 Hibernate JPA 将记录保存到 MySQL。

工作又好又快后,save() 突然开始工作,非常非常慢:插入 1K 条记录大约需要 10 分钟(主键是 ID)。

虽然问题在于循环调用save(),所以我改为saveAll(),但令我惊讶的是没有区别,甚至可能需要20分钟来保存1139 条记录

MySQL 是本地的,仅供我的开发环境使用。

这是日志文件:

2018-08-07 14:44:25:335 - About to save all new 1139 cats of Oscar 
2018-08-07 15:03:47:758 - Succeded saving the cats of Oscar
2018-08-07 15:07:41:961 - Session Metrics {
    600922575 nanoseconds spent acquiring 1140 JDBC connections;
    92320112 nanoseconds spent releasing 1139 JDBC connections;
    312825484 nanoseconds spent preparing 2283 JDBC statements;
    464811479497 nanoseconds spent executing 2279 JDBC statements;
    233368433210 nanoseconds spent executing 229 JDBC batches;
    0 nanoseconds spent performing 0 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    233765441110 nanoseconds spent executing 1 flushes (flushing a total of 1139 entities and 0 collections);
    40198 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
}

我将这些添加到属性文件中:

spring.jpa.properties.hibernate.jdbc.batch_size=5
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.generate_statistics=true

这是Service方法中的代码:

    log.debug("About to save all new {} cats of {} ", allCats.size(), owner);
    catsRepository.saveAll(allCats);
    log.debug("Succeded saving the cats of {}", owner);

【问题讨论】:

标签: java hibernate spring-boot spring-data-jpa


【解决方案1】:

批量大小不会有影响。

这里是来自休眠文档的重要部分: http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#batch-session-batch-insert

批量插入

当你使新对象持久化时,定期对会话使用方法flush()和clear()来控制一级缓存的大小。

示例 3. 刷新和清除 Session

EntityManager entityManager = null;
EntityTransaction txn = null;
try {
    entityManager = entityManagerFactory().createEntityManager();

    txn = entityManager.getTransaction();
    txn.begin();

    int batchSize = 25;

    for ( int i = 0; i < entityCount; i++ ) {
        if ( i > 0 && i % batchSize == 0 ) {
            //flush a batch of inserts and release memory
            entityManager.flush();
            entityManager.clear();
        }

        Person Person = new Person( String.format( "Person %d", i ) );
        entityManager.persist( Person );
    }

    txn.commit();
} catch (RuntimeException e) {
    if ( txn != null && txn.isActive()) txn.rollback();
        throw e;
} finally {
    if (entityManager != null) {
        entityManager.close();
    }
}

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 2020-04-11
    • 2023-03-23
    • 2018-06-18
    • 2021-08-13
    • 2021-03-16
    • 2017-11-29
    • 2018-02-04
    • 2016-06-22
    相关资源
    最近更新 更多