在JPA中阻止N + 1选择 [英] preventing N+1 selects in JPA
问题描述
我有JPA实体订单与Customer的ManyToOne关系。它是双向的,因此Customer也有一个OneToMany字段订单。这两个关系都使用EAGER获取(或者在OpenJPA fetchplan中)。
I have JPA entities Order with a ManyToOne relation to Customer. It is bidirectional, so that Customer also has a OneToMany field orders. Both of the relations use EAGER fetching (or are in the OpenJPA fetchplan).
当我从Order中选择时,我得到1个订单选择和N个选择客户。订单字段。令我惊讶的是,OpenJPA,EclipseLink和Hibernate存在这个问题,即使我使用JOIN FETCH(它在单向情况下工作)。
When I select from Order, I get 1 select for orders and N selects for the Customer.orders field. To my surprise this problem is present with OpenJPA, EclipseLink and Hibernate, even when I use JOIN FETCH (which does work in a unidirectional case).
有没有好方法解决这个问题?
是否有解决更复杂图形的N + 1选择问题的解决方案?
Is there a good way to solve this? Are there any solutions for solving N+1 select problems for more complex graphs?
编辑:我自己研究的结果:
- OpenJPA (我正在使用)我还不知道解决方案
- 对于Hibernate @Fetch(FetchMode.SUBSELECT)解决了这个问题。使用@BatchSize也有帮助,它同时选择给定数量的customer.orders字段。
- 对于EclipseLink,我发现了一个类似的功能@BatchFetch(value = BatchFetchType.IN),但在这种情况下没有帮助,我想它无法以双向关系有效地处理这个问题。
Results of my own research: - For OpenJPA (which I'm using) I don't know a solution yet - For Hibernate @Fetch(FetchMode.SUBSELECT) solves the problem. Using @BatchSize also helps, this selects a given number of customer.orders fields at the same time. - For EclipseLink I found a similar feature @BatchFetch(value=BatchFetchType.IN) but it does not help in this case, I suppose it cannot efficiently handle this in a bidirectional relation.
推荐答案
看看:什么是SELECT N + 1?,因为那里有很多好消息。
Have a look at: What is SELECT N+1? as there lots of good info there.
如果你使用Hibernate: Hibernate - 第19章:提高性能 - 获取策略
If your using Hibernate: Hibernate - Chapter 19: Improving Performance - Fetching Strategies
我个人的解决方案是使用原生SQL和tmp ids表是因为一般恕我直言N + 1选择问题主要是批量处理的问题。否则延迟加载(通常是N + 1解决方案)可能对性能有利。
My own personal solution is to use native SQL and tmp ids table that is because generally IMHO the N+1 select problem is mainly a problem with batch processing. Otherwise lazy loading (typically N+1 solution) can be beneficial to performance.
这篇关于在JPA中阻止N + 1选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!