인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

mingi.kang님의 프로필 이미지
mingi.kang

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

즉시 로딩과 지연 로딩

fetch 조인, 엔티티 그래프 질문입니다.

작성

·

4K

20

안녕하세요. 강의를 들으며 조금 불분명한 부분이 있어서 질문 남깁니다.

가령 멤버들의 팀을 조회하는 쿼리를 작성한다면

우선 팀 전체를 조회하는 쿼리가 실행되고 각 팀이 자신들의 멤버를 조회하는 쿼리가 전체 팀의 수 만큼 발생될것 같습니다.(N+1문제)

이런 경우에는 오히려 즉시로딩을 사용하는게 맞아보이기에 fetch 조인 혹은 그래프 기능을 사용한다고 이해했습니다만 맞게 이해를 한것인지 잘 모르겠습니다.

조금만 더 설명해주시면 정말 감사하겠습니다.

좋은 하루 되세요. 

답변 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

도움이 되셨길 바라며 감사합니다^^

오랜만에 강의를 들어도 이러한 영한님 열정을 다시 한번 느낄 수 있어서 좋네요..ㅎㅎ
감사합니다!

확실히 이해되네요. 감사합니다.

9

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

네 맞습니다^^

조금 더 보충을 해드리자면 JPA에서 모든 연관관계는 꼭! LAZY로 설정하시길 바랍니다. 실무에서 EAGER는 그냥 없다고 생각하시는 것이 더 좋습니다. 그렇게 해야 member만 필요해서 조회할 때, member만 조회가 됩니다.

그런데 때때로 특정 기능에서는 member와 team이 함께 필요한 경우가 있습니다. 이때 그 상황에 맞는 로직에서 fetch join을 사용하면 n+1 문제를 해결할 수 있습니다.

진짜 너무 감사합니다 완벽히 정리 되었습니다 머리속에서 

1

mingi.kang님의 프로필 이미지
mingi.kang
질문자

자세한 답변 정말 감사합니다!

1

mingi.kang님의 프로필 이미지
mingi.kang
질문자

그럼 fetch join은 jpa에서 jpql을 사용하여 데이터를 가져올 때 발생하는 N+1문제를 해결하기 위함이라고 생각해도 될까요..?

엔티티로 LAZY 설정을 작성한 이상 동적 변경이 어렵기 때문
필요에 의해 EAGER 조회를 하고 싶은 경우 JPQL JOIN FETCH 작성.
저는 이렇게 이해했습니다.

mingi.kang님의 프로필 이미지
mingi.kang

작성한 질문수

질문하기