API 개발 고급 - 지연 로딩과 조회 성능 최적화

이가현·2022년 11월 4일
0

간단한 주문 조회에서 벗어나서
주문, 배송정보, 회원을 조회하는 API ➕ 지연 로딩 때문에 발생하는 성능 문제를 해결해보자.

◦ 1. 엔티티 조회 -> DTO로 변환

@GetMapping("/api/v2/simple-orders")
public List<SimpleOrderDto> ordersV2() {
	List<Order> orders = orderRepository.findAll();
    List<SimpleOrderDto> result = orders.stream()
    	.map(o -> new SimpleOrderDto(o))
        .collect(toList());
	return result;
}

지연로딩으로 쿼리 N번 호출하기 때문에 효율적이지 않아서 성능이 상황에 따라서 성능이 저하될 수 있음.

◦ 2. 엔티티 조회 -> DTO로 변환 ( fetch, join 최적화 )

@GetMapping("/api/v3/simple-orders")
public List<SimpleOrderDto> ordersV3() {
	List<Order> orders = orderRepository.findAllWithMemberDelivery();
    List<SimpleOrderDto> result = orders.stream()
    	.map(o -> new SimpleOrderDto(o))
        .collect(toList());
	return result;
}

OrderRepository

public List<Order> findAllWithMemberDelivery() {
      return em.createQuery(
 
		"select o from Order o" +
        " join fetch o.member m" +
        " join fetch o.delivery d", Order.class)
			.getResultList();
}

쿼리 1번에 조회 가능 !

  • order -> member , order -> delivery 는 이미 조회 된 상태 이므로 지연로딩 X

◦ 3. JPA에서 DTO로 바로 조회

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

쿼리 1번에 select절에서 원하는 데이터만 조회 가능 !

💡 쿼리 방식 선택 권장 순서
1. 우선 엔티티를 DTO로 변환하는 방법을 선택한다.
2. 필요하면 페치 조인으로 성능을 최적화 한다. 대부분의 성능 이슈가 해결된다.
3. 그래도 안되면 DTO로 직접 조회하는 방법을 사용한다.
4. 최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접
사용한다.

0개의 댓글