인프런 커뮤니티 질문&답변

ewgregerg c님의 프로필 이미지
ewgregerg c

작성한 질문수

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

간단한 주문 조회 V2: 엔티티를 DTO로 변환

findAllByString() 실행 시 총 쿼리 7번 날아갑니다.

해결된 질문

작성

·

94

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
이전 질문 내역에서 하이버네이트6 최적화 문제라는 답변을 봤는데.. 아직 패치가 안된건지 2024 년에도 총 7번 쿼리날아가네요. 디버깅 해보니

address = order.getDelivery().getAddress();  // LAZY 초기화

이 부분에서

select
        d1_0.delivery_id,
        d1_0.city,
        d1_0.street,
        d1_0.zipcode,
        d1_0.status 
    from
        delivery d1_0 
    where
        d1_0.delivery_id=?

2024-10-22T14:07:35.134+09:00 DEBUG 6578 --- [nio-8080-exec-1] org.hibernate.SQL                        : 
    select
        o1_0.order_id,
        o1_0.delivery_id,
        o1_0.member_id,
        o1_0.order_date,
        o1_0.status 
    from
        orders o1_0 
    where
        o1_0.delivery_id=?

이렇게 두번 쿼리가 실행되네요..

그래서

List<Order> all = orderRepository.findAllByString(new OrderSearch());

여기서 쿼리 한번

 

name = order.getMember().getName();  // LAZY 초기화

여기서 쿼리 한번

 

address = order.getDelivery().getAddress();  // LAZY 초기화

여기서 쿼리 두번

 

주문 리스트가 2개 있으므로

1 + 2 * (1 + 2) = 7 번 실행됩니다.

궁금한 점은

select
        o1_0.order_id,
        o1_0.delivery_id,
        o1_0.member_id,
        o1_0.order_date,
        o1_0.status 
    from
        orders o1_0 
    where
        o1_0.delivery_id=?

이 쿼리는 왜 추가적으로 실행되는지 모르겠습니다.

답변 2

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. ewgregerg c님

이 부분은 저도 확실하지는 않지만 Delivery에서 @OneToOne 관계인 Order를 다시 로딩하는 것으로 추정됩니다. 버전이 올라가면서 이 부분의 최적화가 되지 않은 것으로 추정됩니다.

이 부분은 앞서 링크에서 답변 드린 것 처럼 패치가 될 때 까지는 기다려야 할 것 같아요.

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다. ewgregerg c님.

먼저 쿼리가 예상보다 더 많이 발생하는 문제에 대해 고민이 정말 많으셨을 것 같아요. 질문 주신 부분은 하이버네이트 6 버전과 관련된 이슈로, @OneToOne 매핑을 사용할 때 Eager Fetch 전략 또는 Lazy 전략이 예상과 달리 작동하면서 불필요한 추가 쿼리가 발생하는 경우가 있습니다.

이 부분은 하이버네이트 6의 최적화 문제로 인해 발생할 가능성이 있는 문제로 확인되었습니다. 현재 많은 개발자들이 비슷한 이슈를 겪고 있으며, 하이버네이트 팀에서도 이러한 문제에 대해 피드백을 받아 개선 중인 것으로 보입니다. 이 문제는 하위 버전에서 정상 동작하던 코드가 상위 버전에서 발생할 수 있는 버그에 대한 것으로 볼 수 있습니다.

아직 공식적인 패치가 적용되지 않은 경우, 개발환경 내에서 발생하는 문제를 최소화하기 위해 다음과 같은 고려가 필요할 수 있습니다:

  1. 버전 다운그레이드: 만일 큰 문제가 없다면, 스프링 부트와 하이버네이트 버전을 테스트 목적 또는 임시 조치로 다운그레이드하여 사용을 고려해 보세요.

  2. 명시적 패치 성능 최적화: 직접적으로 문제점을 해결하기 어렵다면, 코드에서 문제 되는 부분을 명시적으로 전환하여 사용해 보세요. Fetch 타입을 조정하거나 필요 시 Custom Query를 사용하여 문제를 회피하는 방법도 한 가지 방법입니다.

함께 유사한 문제를 다룬 다른 질문도 참고하실 수 있습니다:

위 링크들은 하이버네이트와 연관된 쿼리 발생 수와 관련된 다른 예제와 답변입니다. 여기서도 유사한 문제를 다루고 있으니 참고하시기 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

ewgregerg c님의 프로필 이미지
ewgregerg c

작성한 질문수

질문하기