java - 防止在 JPA 中进行 N+1 选择

标签 java sql performance jpa

<分区>

我有 JPA 实体 Order,它与 Customer 有 ManyToOne 关系。它是双向的,因此 Customer 也有一个 OneToMany 字段订单。这两个关系都使用 EAGER 抓取(或者在 OpenJPA 抓取计划中)。

当我从 Order 中选择时,我得到 1 个订单选择和 N 个 Customer.orders 字段选择。令我惊讶的是,OpenJPA、EclipseLink 和 Hibernate 都存在这个问题,即使我使用 JOIN FETCH(它在单向情况下也有效)也是如此。

有什么好的方法可以解决吗? 是否有解决更复杂图形的 N+1 选择问题的解决方案?

编辑:我自己的研究结果: - 对于 OpenJPA(我正在使用)我还不知道解决方案 - 对于 Hibernate @Fetch(FetchMode.SUBSELECT) 解决了这个问题。使用 @BatchSize 也有帮助,这会同时选择给定数量的 customer.orders 字段。 - 对于 EclipseLink,我发现了一个类似的功能 @BatchFetch(value=BatchFetchType.IN) 但它在这种情况下没有帮助,我想它无法在双向关系中有效地处理这个问题。

最佳答案

看看:What is SELECT N+1?因为那里有很多有用的信息。

如果您使用 Hibernate:Hibernate - Chapter 19: Improving Performance - Fetching Strategies

My own personal solution is to use native SQL and tmp ids table那是因为通常恕我直言,N+1 选择问题主要是批处理的问题。否则延迟加载(通常是 N+1 解决方案)可能有利于性能。

关于java - 防止在 JPA 中进行 N+1 选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13400285/

相关文章:

java - 将对象传递给线程(在线程外访问对象)

java - 如何在多同步 Realm 中分离我的 Realm 对象?

mysql - 基本的sql插入语句

php - #1241 - 操作数应包含 1 列 : why?

java - 使用嵌套 Intstream 循环时 Java 8 的性能很糟糕

Java编程任务效率

java - 如何更改 Play Framework 中的模板引擎?

java - 从流中读取 JarEntry

mysql - 使用 SQL 获取车主及其行驶里程

Java 性能 : Getting and Setting Lists