JPA/SpringBoot with JPA

[스프링 부트와 JPA 활용2] 05. API 개발 고급 정리

송재근 2021. 12. 18. 09:59
반응형

정리

  • 엔티티 조회
    • 엔티티를 조회해서 그대로 반환: V1
    • 엔티티 조회 후 DTO로 변환: V2
    • 페치 조인으로 쿼리 수 최적화: V3
    • 컬렉션 페이징과 한계 돌파: V3.1
      • 컬렉션은 페치 조인시 페이징이 불가능
      • ToOne 관계는 페치 조인으로 쿼리 수 최적화
      • 컬렉션은 페치 조인 대신에 지연 로딩을 유지하고, hibernate.default_batch_fetch_size , @BatchSize 로 최적화
  • DTO 직접 조회
    • JPA에서 DTO를 직접 조회: V4
    • 컬렉션 조회 최적화 - 일대다 관계인 컬렉션은 IN 절을 활용해서 메모리에 미리 조회해서 최적화: V5
    • 플랫 데이터 최적화 - JOIN 결과를 그대로 조회 후 애플리케이션에서 원하는 모양으로 직접 변환: V6

 

권장 순서

  1. 엔티티 조회 방식으로 우선 접근
    1. 페치조인으로 쿼리 수를 최적화
    2. 컬렉션 최적화
      1. 페이징 필요 hibernate.default_batch_fetch_size , @BatchSize 로 최적화
      2. 페이징 필요X 페치 조인 사용
  2. 엔티티 조회 방식으로 해결이 안되면 DTO 조회 방식 사용
  3. DTO 조회 방식으로 해결이 안되면 NativeSQL or 스프링 JdbcTemplate

 

참고: 엔티티 조회 방식은 페치 조인이나, hibernate.default_batch_fetch_size , @BatchSize 같이 코드를 거의 수정하지 않고, 옵션만 약간 변경해서, 다양한 성능 최적화를 시도할 수 있다.

반면에 DTO를 직접 조회하는 방식은 성능을 최적화 하거나 성능 최적화 방식을 변경할 때 많은 코드를 변경해야 한다.

 

참고: 개발자는 성능 최적화와 코드 복잡도 사이에서 줄타기를 해야 한다.

항상 그런 것은 아니지만, 보통 성능 최적화는 단순한 코드를 복잡한 코드로 몰고간다.

엔티티 조회 방식은 JPA가 많은 부분을 최적화 해주기 때문에, 단순한 코드를 유지하면서, 성능을 최적화 할 수 있다.

반면에 DTO 조회 방식은 SQL을 직접 다루는 것과 유사하기 때문에, 둘 사이에 줄타기를 해야 한다.

 

DTO 조회 방식의 선택지

DTO로 조회하는 방법도 각각 장단이 있다.

V4, V5, V6에서 단순하게 쿼리가 1번 실행된다고 V6이 항상 좋은 방법인 것은 아니다.

 

V4는 코드가 단순하다.

  • 특정 주문 한건만 조회하면 이 방식을 사용해도 성능이 잘 나온다.
  • 예를 들어서 조회한 Order 데이터가 1건이면 OrderItem을 찾기 위한 쿼리도 1번만 실행하면 된다.

 

V5는 코드가 복잡하다. 여러 주문을 한꺼번에 조회하는 경우에는 V4 대신에 이것을 최적화한 V5 방식을 사용해야 한다.

  • 예를 들어서 조회한 Order 데이터가 1000건인데, V4 방식을 그대로 사용하면, 쿼리가 총 1 + 1000번 실행된다.
  • 여기서 1은 Order 를 조회한 쿼리고, 1000은 조회된 Order의 row 수다.
  • V5 방식으로 최적화 하면 쿼리가 총 1 + 1번만 실행된다.
  • 상황에 따라 다르겠지만 운영 환경에서 100배 이상의 성능 차이가 날 수 있다.

 

V6는 완전히 다른 접근방식이다.

  • 쿼리 한번으로 최적화 되어서 상당히 좋아보이지만, Order를 기준으로 페이징이 불가능하다.
  • 실무에서는 이정도 데이터면 수백이나, 수천건 단위로 페이징 처리가 꼭 필요하므로, 이 경우 선택하기 어려운 방법이다.
  • 그리고 데이터가 많으면 중복 전송이 증가해서 V5와 비교해서 성능 차이도 미비하다.
반응형