작성
·
4K
답변 4
35
안녕하세요. mingi.kang님^^
우선 즉시 로딩과 fetch 조인은 다른 기능입니다.
em.find() 등을 통해서 엔티티 하나만 조회할 때는 즉시 로딩으로 설정하면 연관된 팀도 한 쿼리로 가져오도록 최적화 되지만 JPQL을 사용하면 이야기가 달라집니다. JPQL은 연관관계를 즉시로딩으로 설정하는 것과 상관없이 JPQL 자체만으로 SQL로 그대로 번역됩니다.
예시로 설명해드릴께요.
즉시 로딩(EARGR로 설정)
1. 멤버 전체를 조회하기 위해 JPQL 실행 select m from member m
2. JPQL은 EAGER와 무관하게 SQL로 그대로 번역 -> select m.* from member
3. JPQL 결과가 member만 조회하고, team은 조회하지 않음
4. member와 team이 즉시 로딩으로 설정되어 있기 때문에 연관된 팀을 각각 쿼리를 날려서 추가 조회 (N+1)
지연 로딩(LAZY로 설정)
1. 멤버 전체를 조회하기 위해 JPQL 실행 select m from member m
2. JPQL은 EAGER와 무관하게 SQL로 그대로 번역 -> select m.* from member
3. JPQL 결과가 member만 조회하고, team은 조회하지 않음
4. member와 team이 지연 로딩으로 설정되어 있기 때문에 가짜 프록시 객체를 넣어두고, 실제 회원은 팀은 조회하지 않음
5. 실제 team을 사용하는 시점에 쿼리를 날려서 각각 조회(N+1)
fetch join 또는 엔티티 그래프(EAGER, LAZY 상관 없음)
1. 멤버와 팀을 한번에 조회하기 위해 JPQL+fetch join 실행 select m from member m join fetch m.team
2. JPQL에서 fetch join을 사용했으므로 SQL은 멤버와 팀을 한 쿼리로 조회 -> select m.*, t.* from member join team ...
3. JPQL 결과가 member와 team을 한꺼번에 조회함
4. member와 team이 fetch join으로 한번에 조회되었으므로 N+1 문제가 발생하지 않음
추가로 다음 내용도 보시면 도움이 되실꺼에요. https://www.inflearn.com/questions/30446
도움이 되셨길 바라며 감사합니다^^
1
1
엔티티로 LAZY 설정을 작성한 이상 동적 변경이 어렵기 때문에
필요에 의해 EAGER 조회를 하고 싶은 경우 JPQL JOIN FETCH 작성.
저는 이렇게 이해했습니다.
오랜만에 강의를 들어도 이러한 영한님 열정을 다시 한번 느낄 수 있어서 좋네요..ㅎㅎ
감사합니다!