14

yeoro·2021년 12월 2일
0

지연 로딩과 조회 성능 최적화 (xToOne)

주문 조회 V1

엔티티 노출

  • Order 조회시 연관관계가 있는 Member 조회, Member에서 Order조회, ... 하면 무한루프 발생 > 양방향 관계는 @JsonIgnore 선언으로 해결

  • org.springframework.http.converter.HttpMessageConversionException: Type definition error:

    • 지연로딩은 DB에서 Order만 가져오고, Member는 프록시객체를 생성한다.

      Member member = new ByteBuddyInterceptor();

    • jackson 라이브러리는 프록시 객체를 다룰 수 없으므로 에러 발생.

    • Hibernate5Module로 해결

    • 지연로딩을 즉시로딩으로 바꿔도 성능이 좋아지지는 않는다.

  • 사용하지 않는 OrderItems 등을 불러오면 성능 문제, API 스펙 변경에 유연하지 못 함

주문 조회 V2

DTO 반환

  • Dto에서 엔티티를 파라미터로 받는 것은 문제가 되지 않는다.
  • list.stream().map(o -> X).collect(Collectors.toList()) : list 안의 값들을 X로 바꾸고 list로 반환
  • N + 1 : 1 + (2 + 2)
    • order 조회 1번 (order 2개 꺼냄)
    • order > member 지연 로딩 조회 N번
    • order > delivery 지연 로딩 조회 N번

주문 조회 V3

페치 조인

  • 한방쿼리로 order, member, delivery 조인 후 다 가져오기
  • Lazy 무시, 프록시가 아닌 실제 DB에서 가져옴
  • 기술적으로는 sql의 join, fetch 명령어는 jpa
  • 깊이 있고 성능 최적화에 좋은 기술

주문 조회 V4

JPA에서 DTO 조회

  • 쿼리에서 엔티티를 넘기면 식별자로 인식하고 해당 엔티티의 식별자를 인자로 넘긴다. (o.id)
  • Address는 값 타입이기 때문에 넘겨도 된다.
  • new 명령어를 통해 jpql의 결과를 dto로 즉시 변환
  • repository는 entity를 조회하는데 써야하지만 이 방법은 DTO를 조회하는 것이기 때문에 API 스펙에 의존적이다. > repo 하위 패키지를 만들고 성능 최적화된 쿼리용 repo를 만든다.

V3 vs V4

V3 : 내부에 원하는 것만 페치 조인 하여 성능 튜닝이 가능하다. 쿼리 결과에 정보가 많이 때문에 재사용성이 높다.

V4 : jpql과 Dto를 이용했기 때문에 API 스펙이 repository에 있기 때문에 스펙이 바뀌면 다 바꿔야 한다. V3보다 성능 최적화가 좋다.

하지만 요새는 둘 다 성능 차이가 안 난다.


쿼리 방식 선택

  1. 엔티티를 DTO로 변환하는 방법 선택
  2. 필요하면 페치조인으로 성능 최적화 (대부분 이슈 해결)
  3. 그래도 안되면 DTO로 직접 조회
  4. 최후는 네이티브 SQL, 스프링 JDBC를 사용해서 SQL 직접 사용

0개의 댓글