fetch 조인, 엔티티 그래프 질문입니다.
4355
작성한 질문수 5
안녕하세요. 강의를 들으며 조금 불분명한 부분이 있어서 질문 남깁니다.
가령 멤버들의 팀을 조회하는 쿼리를 작성한다면
우선 팀 전체를 조회하는 쿼리가 실행되고 각 팀이 자신들의 멤버를 조회하는 쿼리가 전체 팀의 수 만큼 발생될것 같습니다.(N+1문제)
이런 경우에는 오히려 즉시로딩을 사용하는게 맞아보이기에 fetch 조인 혹은 그래프 기능을 사용한다고 이해했습니다만 맞게 이해를 한것인지 잘 모르겠습니다.
조금만 더 설명해주시면 정말 감사하겠습니다.
좋은 하루 되세요.
답변 4
34
안녕하세요. 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
그럼 fetch join은 jpa에서 jpql을 사용하여 데이터를 가져올 때 발생하는 N+1문제를 해결하기 위함이라고 생각해도 될까요..?
0
엔티티로 LAZY 설정을 작성한 이상 동적 변경이 어렵기 때문에
필요에 의해 EAGER 조회를 하고 싶은 경우 JPQL JOIN FETCH 작성.
저는 이렇게 이해했습니다.
실무 조언 관련 질문입니다.
0
38
1
H2데이터베이스 파일 생성
0
45
2
서브쿼리 강의에서 ALL 예시 관련 질문드립니다.
0
47
2
수정또는 삭제시 영속성 엔티티에 값이 무조건 있어야 하나요?
0
45
1
JPQL 메소드와 락
0
47
1
Delivery @OneToOne
0
54
1
17강 4~5분대 테이블 값 조회가 안됩니다.
0
85
2
UnsupportedOperationException 발생
0
80
3
H2 Database 연결이 안됩니다.
0
86
2
연관관계 매핑 질문드립니다.
0
77
2
h2데이터베이스 실행오류
0
103
2
persistence.xml
0
101
2
양방향 연관관계에서 연관관계의 주인(mappedBy)을 왜 꼭 정해야 하나요?
0
74
1
영속성 컨텍스트
0
59
1
JPA 프록시
0
87
1
Native Query와 MyBatis
0
61
1
영속성 컨텍스트는 어떤 메모리에 저장되는건가요?
0
81
1
임베디드 타입 예시 코드 관련 질문
0
110
3
명시적 조인에서 별칭을 주면 왜 객체에 접근할 수 있나요
0
89
3
인텔리제이 패키지 커서 단축키 질문
0
100
2
혹시 현재는 ID 데이터 타입이 String이면 안되나요?
0
133
1
양방향 연관관계 시 연관관계 주인을 설정하는 이유
0
67
1
임베디드 타입과 MappedSuperClass의 차이점이 궁금합니다.
0
95
1
데이터베이스가 초기화되는 것 같아요
1
172
2





