【问题标题】:saveAll is too slow for only one tablesaveAll 对于只有一张表来说太慢了
【发布时间】:2020-10-03 13:22:09
【问题描述】:

我在MSSQL 有两张桌子。本质上两者是相同的。但是对于其中之一,当我尝试坚持使用saveAll() 时,这需要很多时间。

我的实体是:

@Data
@Entity
@Table(name = "INSTRUMENTOS_PIP")
@IdClass(value = InstrumentosPIPPk.class)
public class InstrumentosPIP{}

@Data
@Entity
@Table(name = "INSTRUMENTOS_VALMER")
@IdClass(value = InstrumentosValmerPk.class)
public class InstrumentosValmer{}

我的属性:

spring.jpa.properties.hibernate.jdbc.batch_size=20
spring.jpa.properties.hibernate.order_inserts=true

这是我坚持的方式。其中 valmerspips 是大约 25,000 行的列表

vValmer.saveAll(valmers);
            valmers.clear();
            valmers = null;
            System.gc();

vPIP.saveAll(pips);
            pips.clear();
            pips = null;
            System.gc();

valmers 非常快,但 pips 不是。 valmers 花费 5 分钟,点 2 小时。处理顺序无关紧要。

我正在使用JPARepository

【问题讨论】:

  • 您的 MSSQL 服务器接受这么多并行请求的能力如何?

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


【解决方案1】:

您是否尝试过分析您的代码?此外,您可以识别的两个表之间是否有任何差异(例如不同的索引)?

一般来说,JPA 不是批处理操作的理想选择,因为它会引入显着的性能开销。最好使用普通的 JDBC。您可能还会发现 Spring Batch 很方便,特别是如果需要另一个步骤将数据映射到实体(例如从文件中)。

附带说明,您似乎认为valmers.clear(); valmers = null; System.gc(); 释放了占用的内存,但请记住,如果代码本身包装在事务中,那么实体将保留在持久性上下文中。在内存方面,实际上证明将输入分成更小的批次并在保存每个批次后执行JpaRepository.flush() 后跟EntityManager.clear() 更有效。

【讨论】:

    猜你喜欢
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 2013-10-19
    相关资源
    最近更新 更多