가장 추천 : v3 , v3.1
크게 두가지 조회 방법. ->
v1. 엔티티 그대로 반환은 절대 금지 (엔티티가 바뀌면 API도 바뀌므로 안됨.)
v2. 그래도 controller 단에서 DTO로 반환하여 반환하자.
-> v1, v2 는 성능이 안나올 수 있다.
v3. 페치조인으로 쿼리수 최적화. -> 한계 : 컬렉션 페치조인 시 페이징불가. (실무에서는 거의 대부분 페이징사용)
v3-1. 컬렌션 페이징, 한계돌파 ( ToOne관계만 페치 조인하고 컬렌션은 지연로딩 유지하고 hibernate.default_batch_fetch_size(이게 IN쿼리), @BatchSize 로 최적화)
(원래 하나의 order에 연관된 여러개의 orderitem 에 지연로딩으로 쿼리를 다 날리는데(N+1)-> 위 옵션쓰면 IN쿼리로 한번에 정해진 개수만큼 땡겨옴 보통 100개) - 컬렉션 페이징 가능
DTO바로 조회
v4. DTO 직접조회
v5. IN절로 메모리에 미리 조회해서 최적화
v6.
아주 중요한 권장 순서!!!!!
우선 엔티티 조회 -> 페치조인으로 최적화 -> 컬렉션 페이징 필요시 배치 옵션 설정.
보통 페치조인으로 해결이 안되는경우는 트래픽이 진짜 많은 경우인데 -> 이런 상황에서 DTO 직접조회로 해결이 될까 의문이긴함 -> 이럴 땐 그냥 캐시 씀 (대부분 페치조인으로 해결가능)
번외 캐시 이야기.
엔티티는 절대 캐싱하면 안된다. -> 엔티티는 영속성도 있고 상태관리가 되기 때문에 캐시에 잘못 올라가면 굉장히 피곤해짐 -> 영속성컨텍스트가 관리하고 있는데 캐시에 있으면 애매하게 꼬일 수 있음.
캐시는 무조건 엔티티를 DTO로 변환해서 캐시해야됨.
개발자는 성능 최적화와 코드 복잡도 사이에서 줄타기를 해야한다.
엔티티 조회 방식은 JPA가 많은 부분을 최적화 해준다.
(페치조인, 배치패치사이즈 같은 기능들.)
가장 추천 : v5
v4 -> v5는 완전 최적화 많이 됨 . (메모리에 한번에 가져오므로 쿼리가 N+1 -> 1+1)
루프 돌때마다 쿼리 -> 첫 루프에서만 쿼리 (만약 order가 10개라도 그 orderId 여러개 한번에 끌어와서 IN쿼리로 한번에 싹 조회)
-> 페이징 해야되면 v5 쓰자
v6는 v4,v5와 완전히 다른 접근방식.
여기서 join o.orderItems oi 하는 순간 order가 orderItems 의 개수만큼 뻥튀기 되는 것을 알아야한다. (join의 특성)
-> 다시말하지만 oi 기준으로는 페이징 가능 but order기준으로는 페이징 불가.
v6는 페이징 애매함.
실무에서는 결국엔 데이터 끊어와야하므로 페이징 필수다.
결론 :v5써라 (hibernate.default_batch_fetch_size 덕분에 IN절로 한번에 가져올 수 있다.) (어마어마한 기능)
'Java, Spring > 스프링부트와 JPA 활용 2' 카테고리의 다른 글
5-1. OSIV와 성능 최적화 (1) | 2022.09.12 |
---|---|
4-7. 주문 조회 V6: JPA에서 DTO로 직접 조회, 플랫 데이터 최적화 (1) | 2022.09.11 |
4-6. 주문 조회 V5: JPA에서 DTO 직접 조회 - 컬렉션 조회 최적화 (0) | 2022.09.11 |
4-5. 주문 조회 V4: JPA에서 DTO 직접 조회 (1) | 2022.09.11 |
4-4. 주문 조회 V3.1: 엔티티를 DTO로 변환 - 페이징과 한계 돌파 (아주아주아주아주아주 중요) (2) | 2022.09.10 |