【问题标题】:Hibernate how to handle 100.000+ entity updates efficientlyHibernate 如何有效地处理 100.000 多个实体更新
【发布时间】:2015-11-05 03:29:50
【问题描述】:

我有几个客户想要使用 CSV 文件更新他们的数据,典型的客户文件有 1.000 到 20.000 行。

解析行后,我将新数据合并到现有实体中。所有被修改的实体都会使用批量保存:

public void batchSaveOrUpdate(List<Item> items) {
    Transaction transaction = session.beginTransaction();
    List<Item> itemsToEvict = new ArrayList<>();

    int count = 0;
    for (Item item : itemss) {
        session.saveOrUpdate(item);
        itemsToEvict.add(item);

        if (count++ % 25 == 0) {
            session.flush();
            itemsToEvict.forEach(session::evict);
            itemsToEvict.clear();
        }
    }

    transaction.commit();
    session.flush();
}

它适用于最多 25.000 行的正常导入,但现在我有一个客户,其 CSV 文件包含最多 600.000 行。 即使在确定已修改的项目之后,也有 100.000 多个实体已立即更新。 由于一段时间后所有交易都被 WildFly 收割,因此大客户的所有导入都失败了。 我已经将事务超时增加到一小时,进一步增加对我来说没有解决办法。

此时我可以做些什么来提高休眠更新性能?

【问题讨论】:

  • 每 25 件物品上的刷新似乎是问题所在。在每次刷新时,会话都会与数据库同步。你试过没有吗?
  • 就个人而言,对于 600k 行,我非常倾向于绕过 Hibernate 并在 SQL 级别进行批量 upsert/merge。

标签: hibernate postgresql jakarta-ee


【解决方案1】:

确保您实际使用的是批处理。正确配置批处理相关属性:

<property name="hibernate.jdbc.batch_size">100</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>

这里我将jdbc.batch_size 设置为100;在刷新会话之前,此值应与已处理项目的数量相匹配(在您的情况下为 25;也许您应该尝试更多,例如 100)。

此外,您正在明确驱逐项目。如果Item 与其他实体关联,并且在关联中既没有指定级联类型ALL 也没有指定DETACH,则驱逐不会级联到相关实体,它们将消耗大量堆,因为 Hibernate 会将它们保留在持久性上下文(会话),因此如果有数十万个,则会显着降低应用程序的性能。

确保分离(驱逐)整个对象图,或清除整个会话并读取下一个要处理的项目块。

【讨论】:

  • persitence.xml中的batch size已经配置为25,我再试试增加batch size。
【解决方案2】:

您可以尝试编写自己的存储过程。 Hibernate 不是最适合您的需求..

【讨论】:

  • 我尽量避免向数据库添加任何类型的业务逻辑,即使这个解决方案会更快……但如果没有其他帮助,我会牢记这个想法。
【解决方案3】:

首先CopyManager 是将CVS 复制到postgres 的最有效方式。可能您应该创建一些临时表,然后复制 CSV,然后执行一组插入/更新 SQL 语句。获取 PGConnection 和 CopyManager 可能会很棘手。例如。如果你使用c3p0连接池是不可能的。

同样重要的是,根据Chapter 4. Batch Processing

如果您使用身份标识符生成器,​​Hibernate 会在 JDBC 级别透明地禁用插入批处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 2012-09-26
    • 2012-03-30
    • 1970-01-01
    相关资源
    最近更新 更多