오봉이와 함께하는 개발 블로그

JPA 2 - API 개발 고급 정리 본문

BE/JPA

JPA 2 - API 개발 고급 정리

오봉봉이 2022. 9. 7. 00:02
728x90

API 개발 고급 정리

엔티티 조회

  • 엔티티를 조회해서 그대로 반환 : V1
    • 엔티티 스펙이 변하면 API 스펙이 변하기 때문에 사용하지 말자.
  • 엔티티 조회 후 DTO로 변환 : V2
    • 여러 테이블을 조인해야 하면 성능이 안 나올 수 있다.
  • 페치 조인으로 쿼리 수 최적화 : V3
    • V2에서 성능이 안 나오면 페치 조인을 통해 성능 향상
  • 컬렉션 페이징과 한계 돌파 : V3.1
    • 컬렉션(XToMany)은 페치 조인시 페이징이 불가능
    • XToOne 관계는 페치 조인으로 쿼리 수 최적화
    • 컬렉션(XToMany)은 페치 조인 대신에 지연 로딩을 유지
      • hibernate.default_batch_fetch_size, @BatchSizein 쿼리를 사용해서 최적화

DTO 직접 조회

  • JPA에서 DTO를 직접 조회 : V4
  • 컬렉션 조회 최적화 - 일대다 관계인 컬렉션은 IN 절을 활용해서 메모리에 미리 조회해서 최적화 : V5
    • 일대다 관계는 조인해서 가져오면 데이터가 뻥튀기 될 수 있다.
    • 에 맞춰서 데이터를 만들고 싶으면 는 IN 절을 활용해서 미리 조회하고 루프를 통해 에 맞게 데이터를 맞추자.
  • 플랫 데이터 최적화 - JOIN 결과를 그대로 조회 후 애플리케이션에서 원하는 모양으로 직접 변환 : V6
    • 모든 데이터를 메모리에 올려놓고 애플리케이션 내부에서 데이터를 발라내서 원하는 모양으로 반환한다.

권장 순서

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

엔티티 조회 방식은 페치 조인이나, hibernate.default_batch_fetch_size, @BatchSize같이 코드를 거의 수정하지 않고 옵션만 약간 변경해서 다양한 성능 최적화를 시도할 수 있다. 반면에 DTO를 직접 조회하는 방식은 성능을 최적화 하거나 성능 최적화 방식을 변경할 때 많은 코드를 변경해야 한다.

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와 비교해서 성능 차이도 미비하다.
인프런 김영한 지식공유자님 강의 - 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
728x90
Comments