https://jbluke.tistory.com/426 ( 이 사이트의 맥락에 이어서 설명을 하겠다)
컬렉션(Collection) fetch join 시, 발생하는 [데이터 중복] 문제!(소위 [데이터 뻥튀기]라고도 부름)
[1:다]에서 생기는 문제이기도 함. (아래 사이트 참조) (하이버네이터 6부터는 자동으로 데이터 중복 해결해줌. (Feat. distinct) https://jbluke.tistory.com/346 1:多 jbluke.tistory.com @Entity @Table(name = "ORDERS") @Ge
jbluke.tistory.com
그럼, [1:다] 관계에서 발생하는,즉 컬렉션(다) 조회 시 발생하는 [페이징] 이슈를 해결할 방법은 없는건가???
(참고로, [1:다]에서 생기는 이슈는 [다:다]에서도 똑같이 생기는데, [다:다] 관계는 절대 사용하면 안된다. 고로,
컬렉션 문제는 [1:다]로 한정하고 생각해도 평생 문제 없음)
해결 방법은 아래 방법 밖에 없다. (ppt 26)
1] 먼저 ToOne(Member,Delivery) 관계를 모두 페치조인 한다(Order입장에서 ToOne 관계는 Member, Delivery)
-> ToOne 관계는 row수를 증가시키지 않으므로 페이징 쿼리에 영향을 주지 않는다.
-> @~ToOne 관계는 fetch join으로 (1+N) 문제를 해결하겠다는 뜻이다.
(@~ToOne 관계는 애초에 [페이지] 이슈가 생기지 않으므로, 1]에서는 [페이지]에 대한 내용은 없다)
2] 컬렉션(OrderItem)은 지연 로딩(Lazy)으로 [조회]한다( [ 1 : 다] 관계에서의 [다] 쪽을 Lazy 조회 )
-> 즉 [1:다] 관계에서 다(컬렉션)은 fetch join으로 조회x.
Lazy를 걸어서, 직접 호출하는 방식으로 조회를 하나????????
Nope!!! Lazy를 때문에 생기는 (N+1) 문제는 Fetch Join이 아니더라고 유일하게 아래의 방법으로
최적화가 가능하다.
3] 지연 로딩 성능 최적화를 위해 hibernate.default_batch_fetch_size , @BatchSize 를 적용한다.
->hibernate.default_batch_fetch_size : 글로벌 설정
@BatchSize: 개별 최적화
이 옵션을 사용하면 컬렉션이나, 프록시 객체(ITEM)를 한꺼번에 설정한 size 만큼 IN 쿼리로 조회한다.
-> 1] -> 2] ->3] 순으로 [1:다] 관계에 있어서의 컬렉션(OrderItem) 조회 이슈를 해결한다.
( 1] : 이 과정에서 제일 먼저, Member, Delivery가 fetch join되어 조회된다[여기서 페이징이 일어남. 절대 컬렉션인 OrderItem을 조회할 때 일어나면 안됨. 그런면 페이징 이슈 해결이 안됨.]
2]-1 : 이 과정에서 OrderItem(컬렉션)이 설정된 fetch_size만큼 조회된다.
2]-2 : OrderItem이 조회되면 이제 Proxy 객체인 ITEM에 대해서도 fetch_size만큼 조회된다.
)
정확한 것은 게시물 428을 참고하면 된다.
'CS 잡지식' 카테고리의 다른 글
batch_size의 설정 TIP!!(batch_fetch_size, @BatchSize) (0) | 2023.05.05 |
---|---|
(1 + N) 문제 해결책 - (Feat. Fetch Join, @BatchSize, batch_fetch_size 설정) (0) | 2023.05.05 |
컬렉션(Collection) fetch join 시, 발생하는 [데이터 중복] 문제!(소위 [데이터 뻥튀기]라고도 부름) (0) | 2023.05.05 |
DTO는 그 어떠한 [도메인 엔티티]를 의존해서는 안된다 (0) | 2023.05.04 |
컬렉션(Collection) 조회 시 생기는 [데이터 중복] 문제(미완성) (0) | 2023.05.04 |