해결된 질문
작성
·
271
1
다른 분이 질문글에 잘 정리된 표를 올려주셔서 이것을 이용해 비교를 해보고 있습니다.
위 경우의 수에 번호를 붙여 왼쪽부터 차례로 ①~④ 번호를 매겼습니다.
질문1)
강의 5분15초에 상황을 볼 때
위 그림③의 다른 점 한가지가 즉시로딩 입니다. 따라서 그림과 다르게 "Team 각각 N쿼리"가 윗 칸인 "User호출시점"에서 실행됩니다. 강의에서 잘 확인할 수 있었습니다.
그런데, JPQL에 setFirstResult(1).setMaxResult(10) 를 적용하면 1쿼리는 발생하지만 N쿼리가 질의되지 않은 것을 발견했습니다.
페이징을 적용하면 로딩방식이 Eager로 설정해도 무조건 Lazy로 진행이 되는 것인지요?
질문2)
강의 5분15초에 상황에서 Eager설정을 유지하면서
SELECT m, t FROM Member m INNER JOIN m.team t
으로 프로젝션에 t를 추가했습니다. p.380 예제 10.35처럼(위 ④번) fetch조인의 SQL번역된 형식을 [일반JOIN + Eager]으로 모방할 수 있지않을까 궁금하여 실험해봤습니다.
결과는 SELECT문 질의가 발생하지 않았습니다.
왜 이런 결과가 나온것인지 궁금합니다.
답변 1
0
안녕하세요. ddoddo님
테스트 해보신 것 둘다
아마 테스트 데이터가 부족하거나 아직 영속성 컨텍스트에 데이터가 남아있어서 캐시가 호출되어서 그런 문제가 발생할 거에요.
충분한 테스트 데이터를 추가하시고, 그 다음에 em.flush(), em.clear()를 호출해서 영속성 컨텍스트에 남아있는 엔티티를 제거한 다음에 다시 조회해보시면 원하는 결과를 보실 수 있을거에요.
감사합니다.
select m, t from Member m join m.team t는 사실 좀 특수한 경우입니다.
이렇게 사용하는 일은 거의 없습니다.
이게 성능 최적화가 된 것 처럼 보이는 이유는 다음과 같습니다.
JPA에서 엔티티를 조회하게 되면 엔티티는 모두 영속성 컨텍스트에 올라갑니다.
따라서 쿼리의 결과인 member도 모두 영속성 컨텍스트에 올라가고 team도 영속성 컨텍스트에 올라갑니다.
member.getTeam()을 호출하게 되면 지연로딩이 발생하는데, 방금 쿼리에서 team도 영속성 컨텍스트에 올라갔기 때문에 이미 로딩된 엔티티를 사용하게 됩니다.
fetch join은 명확하게 한번에 조회한다는 의미이기 때문에 성능 최적화가 필요하면 명확하게 fetch join을 사용해주세요.
감사합니다.
선생님, 죄송합니다.
몇 가지 실수를 발견했습니다. 그 때는 한 참 찾아도 못찾더니 지금와서 눈에 들어왔습니다ㅠㅠ
[질문1]
원인 : setFirstResult(1) 와 한 개의 입력데이터
행 1줄을 넣었기 때문에 setFirstResult( 1 ) 코드를 제거해야 정상인 결과를 얻을 수 있었습니다. setFirstResult( 1 )을 넣고 진행했던 강의실습을 그대로 따라갔다가 getResultList( )로 얻은 빈 리스트를 얻게 되었고 리스트에 요소가 없기 때문에 이후 Eager로딩으로 추가 N쿼리가 발생하지않았던 것입니다.... 흑흑
[질문2]
SELECT m, t FROM Member m INNER JOIN m.team t 으로 질의를 할 때
em.createQuery(query, Member.class); 만 적었는데요. 이것이 실수였습니다.
프로젝션을 m, t로 잡았기 때문에 두 번째 파라미터는 제거를 해줘야 했습니다.(컴파일에러가 없어서 못 찾았은 거라 핑계를 대고 싶습니다)
잘못된 오류를 고치고 정상적으로 실행된 결과를 fetch조인과 비교해 보니 완전히 같은 것을 알 수 있었습니다.
즉,
select m from Member m join fetch m.team t (fetch 조인)
select m, t from Member m join m.team t (내부 조인 + 프로젝션명시)
위 두 JPQL은 동일한 SQL쿼리로 변환되는 것을 확인할 수 있었습니다.
https://www.inflearn.com/questions/282782 예전에 질문글에 선생님께서 답변을 달아 주신적이 있었는데요. 저는 위 두 JPQL이 동일한 한 방 쿼리 결과를 만들어내 N+1문제를 해결해준다고 정리를 했습니다.
상세한 정리는 아래 링크에 있습니다.
링크 (다른 수강생분이 잘 정리된 표로 아이디어를 주셔서 응용하여 더 자세한 경우의 수를 정리해 봤습니다.)
혹시나 잘못된 결론을 내린거라면 어떤 부분이 틀렸는지 조언부탁드립니다.
감사합니다.