출처
본 글은 인프런의 김영한님 강의 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
을 수강하며 기록한 필기 내용을 정리한 글입니다.
-> 인프런
-> 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화 강의
API 개발 고급 정리 - 엔티티로 조회
- V1 : 엔티티를 조회해서 그대로 반환
- V2 : 엔티티를 DTO로 변환
- V3 : 페치 조인 적용
- 컬렉션(
@~~ToMany
)도 같이 페치 조인 적용할 경우, 중복 제거를 위한 Distinct 적용
- 페이징 불가능
- V3.1 : 컬렉션 페이징 및 한계 돌파
@~~ToOne
관계는 페치 조인으로 한번에 가져옴
@~~ToMany
관계는 지연 로딩으로 가져옴
- batch size 설정으로 최적화
- 페이징 가능
API 개발 고급 정리 - DTO로 바로 조회
- V4 : JPA에서 DTO로 바로 조회
- V5 : IN 조건절 적용
- 컬렉션 빼고 DTO로 바로 조회
- 컬렉션은 IN 조건절에 넣을 값들 List로 뽑아서 적용
- 쿼리 1 + 1번
- V6 : Flat 데이터 최적화
- 아예 필요한 데이터들 뽑기 위한 전체 테이블 싹다 조회
- 조회된 결과로부터 중복 제거하면서 API 스펙에 맞춘 DTO로 변환하는 로직 추가
- 쿼리 1번
권장 순서
- 일단 엔티티 조회 방식으로 접근 및 최적화 적용
- 페치 조인으로 쿼리 수 최적화
- 컬렉션 최적화 적용
- 페이징 필요할 경우 : batch size로 최적화
- 페이징 불필요한 경우 : 페치 조인 + distinct 사용
- 엔티티 조회 방식으로 성능 개선이 안되면 DTO 조회 방식 적용
- DTO 조회 방식으로 해결이 안되면 NativeSQL 또는 Spring JDBC Template 활용
DTO 직접 조회 방식 대비 엔티티 조회 방식의 장점
- 페치 조인 활용, batch size 설정 등 코드를 거의 수정하지 않고 옵션만 조금씩 변경해서 다양한 성능 최적화를 시도할 수 있다.
- 반면 DTO로 직접 조회하는 방식은 성능 최적화를 적용할 때나 성능 최적화 방식을 변경할 때 많은 코드를 변경해야 한다.
- 엔티티 조회 방식은 JPA가 많은 부분을 최적화 해주므로 단순한 코드를 유지하면서 성능을 최적화 할 수 있다.
- 반면 DTO 조회 방식은 SQL을 직접 다루는 것과 유사하므로 코드 복잡도와 성능 최적화 사이에서 줄타기를 해야한다.
+유의할점 : 엔티티는 직접 캐시에 저장하면 안된다.
DTO 직접 조회 방식 선택지
- DTO로 조회하는 방식도 V4, V5, V6 모두 장단점이 있다. V6가 무조건 좋은 건 아니다.
- V4
- 코드가 단순한다.
- 특정 주문 한건만 조회하는 경우, V4를 사용해도 성능은 잘 나온다.
- Order 엔티티에 딸린 OrderItem이 1개밖에 없으면 OrderItem을 조회하는 쿼리도 1번만 실행된다.
- V5
- 코드가 복잡하다.
- 여러 주문을 한꺼번에 조회하는 경우, V4를 최적화한 V5를 사용해야 한다.
- 만약 처음 조회된 Order 엔티티의 조회 결과가 1000건인데, V4 방식을 활용하게 될 경우 1 + 1000 번의 쿼리가 전송된다.
- 하지만 V5 방식을 활용할 경우, 1 + 1번만 쿼리가 나간다.
- 상황에 따라 차이는 있지만 운영 환경에서 100배 이상 성능이 차이날 수 있다.
- V6
- 완전히 다른 접근 방식이다.
- 쿼리가 1번만 전달돼서 되게 좋아보일 수 있지만, Order를 기준으로 페이징이 불가능하다.
- 실무에서도 보통 쿼리가 1번만 나가도록 최적화 시켜야 하는 상황이면 수백, 수천건 단위로 페이징 처리가 꼭 필요하기 때문에, 이럴 때 V6는 선택하기 어려운 방법이다.
- 또한 데이터가 많으면 중복 데이터도 그만큼 많아져서 V5와 비교했을 때 성능 차이도 미비하다.