스프링데이터 + JPA/API 개발

8. fetch join 최적화

sdafdq 2023. 11. 13. 18:06
@GetMapping("/api/v3/simple-orders")
public List<SimpleOrderDto> orderV3(){
    List<Order> orders = orderRepository.findAllWithMemberDelivery();

    List<SimpleOrderDto> result = orders.stream()
            .map(o-> new SimpleOrderDto(o))
            .collect(Collectors.toList());

    return result;
}

똑같은 데, 저 DB에서 가져오는 걸 findAllWithMemberDelivery()라는 걸 만들어서 가져올 거다.

메소드 이름이 거지같긴 한데, 보통은 주문이면 member와 delivery 가져와야 한다 이정도로 어느 정도 자주 쓰는 객체 그래프가 정해져 있기 때문에 그냥 findAll이라고 이름 붙이고 쓰기도 한다.

 

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();
}

비법은 join fetch이다.

 

join fetch 하면 저거는 그냥 한번에 쫙 끌고 오는건데,

select
    o1_0.order_id,
    d1_0.delivery_id,
    d1_0.city,
    d1_0.street,
    d1_0.zipcode,
    d1_0.status,
    m1_0.member_id,
    m1_0.city,
    m1_0.street,
    m1_0.zipcode,
    m1_0.name,
    o1_0.order_date,
    o1_0.status 
from
    orders o1_0 
join
    member m1_0 
        on m1_0.member_id=o1_0.member_id 
join
    delivery d1_0 
        on d1_0.delivery_id=o1_0.delivery_id

진짜 쿼리가 이 한방으로 나간다.

실무의 90% 성능 문제는 이 join fetch로 해결한다.

 

참고로, join fetch의 경우 LAZY, 지연 로딩은 무시된다.

 

https://qwefdg3.tistory.com/782

https://qwefdg3.tistory.com/791

 

join fetch는 JPA의 개념으로 다 끌고온다는 느낌임. 뭐 따로 delivery의 zipcode만 가져온다던지 그런 거 말고, 그냥 다 끌고온다는 개념으로 잡고 개발을 한 거임.

그래서 join fetch에 별칭을 못씀. join fetch o.member m 이렇게 해서 가져와도 저 m을 못씀.

 

이 join fetch로 실무의 성능문제 90%를 해결함.

'스프링데이터 + JPA > API 개발' 카테고리의 다른 글

10. 컬렉션 조회 최적화  (0) 2023.11.14
9. 바로 Dto로 받기  (0) 2023.11.14
7. 엔티티를 Dto로  (0) 2023.11.13
6. 지연로딩과 조회성능 최적화  (0) 2023.11.13
5. 조회용 샘플 데이터 입력  (0) 2023.11.12