gpt4 book ai didi

java - 使用@batchsize 后jpa 性能崩溃

转载 作者:搜寻专家 更新时间:2023-11-01 02:30:24 25 4
gpt4 key购买 nike

我有一个 java jpa/hibernate 应用程序需要获取大量数据才能执行其任务。我遇到了 n+1 问题,所以我决定使用 hibernate.default_batch_fetch_size (@batchsize) 属性来降低所需的 sql 往返次数。我尝试了一些值,但几乎所有尝试值的性能都崩溃了。

批量大小:0 - 发送的 sqls:14000 - 持续时间:大约 1 分钟

批量大小:4 - 发送的 sqls:5000 - 持续时间:超过 10 分钟

批量大小:10 - 发送的 sqls:2700 - 持续时间:大约 5 分钟

批量大小:100 - 发送的 sqls:400 - 持续时间:大约 1 分钟

这是“正常”行为吗?如果不是,可能是什么错误?

我用 log4jdbc 记录了生成的 sql。我注意到在每个批处理语句之间有大约 100-150 毫秒的谎言。如果我稍后运行 sql,则每个语句的运行时间不超过 20 毫秒。因此,这并不是与数据库(IN 语句)相关的问题。

Java:1.6.0_31、Hibernate 3.6.7、DB Postgres 9.1.1、JDBC postgresql-9.1-901.jdbc4.jar

提前致谢

更新明确一点:性能损失是在批量获取期间而不是批量更新/插入期间

最佳答案

经过一些调试,我发现了问题。 Hibernate(至少在版本 3.6.7 中)将所有映射的集合存储在映射中。您可以使用如下代码片段访问这些 map :

SessionImpl si = ((SessionImpl) entityManager.getDelegate());
PersistenceContext persistenceContext = si.getPersistenceContext();
persistenceContext.getCollectionEntries();

所以每个集合都会在这张 map 中创建一个条目。如果你有很多集合的 pojos,就像我的情况一样,它会很快变大。例如,每 32 个集合加载 10.000 个 pojo,您有 320.000 个集合条目。 Hibernate 现在只是遍历映射 (org.hibernate.engine.BatchFetchQueue.getCollectionBatch(CollectionPersister, Serializable, int, EntityMode)) 来查找未加载的集合 id,以便稍后将它们放入 IN 子句中。 Hibernate 不限制对特定类型集合的键的搜索,因此这变得更糟。

我想我必须清理一些集合,并希望 hibernate 能以更有效的方式在更高版本中查找 key 。

更新:对于有同样问题的人来说,这个关于 hibernate jira 的评论可能很有趣: https://hibernate.onjira.com/browse/HHH-1775?focusedCommentId=42686&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-42686

更新:此问题已在 hibernate 版本中得到解决:4.1.8

关于java - 使用@batchsize 后jpa 性能崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10834573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com