[스프링과 JPA활용 2편] API 개발 中 컬렉션 조회 정리

sonnng·2023년 11월 4일
0

Spring

목록 보기
29/41

컬렉션 조회의 종류에는 [엔티티로 조회하는 경우]와 [DTO로 직접 조회하는 경우]로 나뉜다.

이전까지 작성했던 블로그 글을 살펴보면

엔티티 조회

  • 엔티티를 조회해서 그대로 반환(V1)
  • 엔티티를 조회해서 DTO로 변환(V2)
  • 페치조인으로 쿼리수 최적화(V3)
  • 컬렉션 페이징과 한계 돌파(V3.1)
    - 컬렉션은 페치 조인할 때 페이징이 불가능하다.
    <span style="background-color: rgba(242,179,188,0.5)">**ToOne 관계는 페치조인으로 쿼리수를 최적화시키고, 컬렉션은 페치조인 대신 지연로딩을 유지하며 `hibernate.default_batch_fetch_size`, 
    @BatchSize 옵션을 추가해서 최적화한다.**

DTO 직접 조회

  • JPA에서 DTO를 직접 조회(V4)
  • 컬렉션 조회 최적화하기 위해, 일대다 관계인 컬렉션을 IN절을 통해 메모리에 미리 조회해서 최적화한다.(V5)
  • 플랫 데이터 최적화하기 위해, JOIN결과를 그대로 조회하여 애플리케이션이 원하는 모양으로 직접 변환하는 방법이다.(V6)


컬렉션 조회 적용 권장 순서

  1. 엔티티 조회 방식으로 우선 접근한다.
    1. 페치조인으로 쿼리수를 최적화하고(ToOne관계)

    2. 컬렉션 최적화를 수행한다.

      1. 페이징이 필요한 경우
        hibernate.default_batch_fetch_size, @BatchSize 옵션을 추가해서 최적화한다.

      2. 페이징이 필요없는 경우
        페치조인을 사용한다.

  2. 엔티티 조회방식으로도 해결이 안된다면 DTO조회방식을 사용한다.
  3. DTO 조회방식으로도 해결이 안되면, NativeSQL, JdbcTemplate을 사용한다.

엔티티 조회방식은 페치조인이나 위에서 작성한 옵션처럼 hibernate.default_batch_fetch_size, @BatchSize 같은 옵션만 조금 추가하기만 하면 다양한 최적화가 가능하다.

보통의 성능 최적화는 단순한 코드를 복잡한 코드로 몰고간다는 특징이 있다. 엔티티 조회방식은 JPA에서 상당부분 최적화를 진행해주므로, 단순한 코드를 작성할 수 있으면서도 성능을 최적화할 수 있다. 반면 DTO 조회방식은 SQL을 직접 다루므로 이 두 방식 중에 골라서 구현하면 되겠다.



DTO 조회방식의 선택지

예로 든 V4, V5, V6 총 3가지 방법이 있었다. 항상 6번이 항상 좋은 방법은 아니다.

  • v4는 코드가 단순하며, 단순하기 때문에 유지보수성이 뛰어나다.

하지만, 이런 컬렉션 조인은 데이터뻥튀기가 가능하기 때문에 특정 주문 한건만 조회하는 경우만 사용해야 하고 성능이 잘 나온다.

  • V5는 코드가 복잡하며, 여러 주문을 한꺼번에 조회하는 경우에 V4대신 최적화된 v5를 사용하는 것을 권장한다.

총 쿼리가 루트 1번+추가 1번 총 2번이 실행되기 때문이다. 운영환경에 따라 100배 이상의 성능차이가 날 수 있다.

  • V6는 완전 다른 접근 방식이다. Order 기준으로 페이징이 불가능하다.

컬렉션이 펼쳐진 뻥튀기된 데이터들을 기준으로 페이징이 되므로 원하는 대로 Order기준으로 페이징이 불가능하고 이상한 페이징 처리가 되어버린다. 그리고 데이터가 많으면 중복전송이 증가해서 성능차도 미비하다는 특징이 있다.

0개의 댓글