nu_s

[JPA 활용] 조회 성능 최적화 - JPA에서 DTO로 조회🐱 본문

JPA

[JPA 활용] 조회 성능 최적화 - JPA에서 DTO로 조회🐱

woochii 2023. 11. 10. 16:15
728x90
반응형

V4. JPA에서 DTO로 바로 조회하기

  • 쿼리 한 번 호출
  • select 절에서 원하는 데이터만 선택해서 조회
@RestController
@RequiredArgsConstructor
public class OrderSimpleApiController {

    private final OrderSimpleQueryRepository orderSimpleQueryRepository;

    @GetMapping("/api/v4/simple-orders")
    public List<OrderSimpleQueryDto> ordersV4() {
        return orderSimpleQueryRepository.findOrderDtos();
    }
}

 

OrderSimpleQueryRepository (조회 전용 리포지토리)

@Repository
@RequiredArgsConstructor
public class OrderSimpleQueryRepository {
    
    private final EntityManager em;
    
    public List<OrderSimpleQueryDto> findOrderDtos() {
        return em.createQuery(
                "select new jpabook.jpashop.repository.order.simplequery.OrderSimpleQueryDto(o.id, 
m.name, o.orderDate, o.status, d.address)" +
                " from Order o" +
                " join o.member m" +
                " join o.delivery d", OrderSimpleQueryDto.class)
            .getResultList();
    }
}

 

OrderSimpleQueryDto (리포지토리에서 DTO 직접 조회)

@Data
public class OrderSimpleQueryDto {

    private Long orderId;
    private String name;
    private LocalDateTime orderDate; //주문시간 
    private OrderStatus orderStatus;
    private Address address;
    
    public OrderSimpleQueryDto(Long orderId, String name, LocalDateTime orderDate, OrderStatus orderStatus, Address address) {
        this.orderId = orderId;
        this.name = name;
        this.orderDate = orderDate;
        this.orderStatus = orderStatus;
        this.address = address;
    }
}

 

실행 쿼리

select
    order0_.order_id as col_0_0_,
    member1_.name as col_1_0_,
    order0_.order_date as col_2_0_,
    order0_.status as col_3_0_,
    delivery2_.city as col_4_0_,
    delivery2_.street as col_4_1_,
    delivery2_.zipcode as col_4_2_
from
    orders order0_
inner join
    member member1_
        on order0_.member_id=member1_.member_id
inner join
    delivery delivery2_
        on order0_.delivery_id=delivery2_.delivery_id

원하는 데이터만 select하도록 최적화 되었다.

 

장점

V4는 일반적인 SQL을 사용할 때 처럼 원하는 값을 선택해서 조회하고 new 명령어를 사용해서 JPQL의 결과를 DTO로 즉시 변환한다.

  • V3 페치조인 경우에는 기본적으로 데이터를 더 많이 퍼오기 때문에 네트워크 사용량이 V4보다 비교적 크다.
  • V4에서는 컴팩트하게 정확하게 원하는 데이터만 선택하여 쿼리를 조회한 것이기 때문에 V3보다 성능이 좋다.

 

단점

언뜻 보기엔 성능을 높여주기 때문에 좋아보이지만 유연성이 떨어진다.

  • V4는 특정 API 스팩에만 맞춰 딱 맞게 제작한 것이기 때문에 해당 DTO에만 한정되어있다는 단점이 있다. 따라서 해당 코드는 재사용이 거의 불가능하다고 보면 된다.
  • 반면 V3는 원하는 엔티티에 페치조인만 적용하였기 때문에 공용으로 사용이 가능하다.
  • V4는 V3보다 성능이 좋긴 하지만 전체적인 애플리케이션 관점에서 성능 향상은 미비하다.

조회성능 최적화 정리

쿼리 방식 선택 권장 순서

  1. 엔티티를 DTO로 변환하는 방법을 선택한다. (V2)
  2. 필요하면 페치 조인으로 성능을 최적화한다. (V3)
  3. 그래도 안되면 DTO로 직접 조회하는 방법을 사용한다. (V4)
  4. 최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접 사용한다.

출처 : 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

728x90
반응형