[JPA] Fetch 전략

Welcome to Seoyun Dev Log·2023년 5월 9일
0

JPA

목록 보기
13/15

Fetch

애플리케이션이 DB로부터 데이터를 가지고 오는 것
DB와 통신하여 데이터를 읽는 것에는 큰 비용이 소모되기 때문에 이를 해결하는 전략

Fetch 전략

fetch 전략에는 FetchType.EAGER(즉시로딩), FetchType.LAZY(지연로딩) 2가지 설정이 있다

  • EAGER:즉시로딩
    : 연관 관계에 있는 Entity를 전부 로딩해서 영속성 컨텍스트에 올리고 모두 가져온다
    @ManyToOne, @OneToOne은 기본값으로 즉시로딩으로 설정되어 있다.

    • EAGER 사용: 연관 관계가 있는 엔티티에서 무조건 다 가져오는 시나리오일 때
  • LAZY:지연로딩
    : 연관관계에 있는 Entity를 가져오지 않고 호출 시 가져온다
    다른 Entity를 조회 시 해당 테이블의 프록시 객체를 가져온다(참조 값)
    (team과 member Entity가 있을때 team.findAll()을 한 순간 team 데이터만 가져오고 member를 사용하려고 하면 이때 N+1문제가 발생하는 것)
    @OneToMany와 @ManyToMany는 기본값으로 지연로딩으로 설정되어 있다.

    • LAZY 사용: 연관 관계가 있는 엔티티에서 자식 엔티티만 가져오는 시나리오일 때

Fetch VS Fetch Join

  • Fetch전략은 특정 엔티티를 조회할 때 연관관계에 있는 다른 엔티티를 언제 불러올까에 대한 옵션이다.
  • Fetch join은 JPQL 만의 조회를 위한 join 방식이다.

N + 1 문제

연관 관계에서 발생하는 이슈로 연관관계가 설정된 엔티티를 조회할 때 조회한 갯수보다 쿼리가 더 나와 성능 저하를 이르키는 것

: 연관관계 매핑시 즉시로딩의 경우 N+1의 문제가 발생한다
해당 Entity를 조회해도 연관관계가 맺어져 있는 엔티티 쿼리도 조회된다 이 문제를 N+1이라고 한다.

예를 들어 멤버 테이블과 팀 테이블이 N:1 관계에 있을 때, 멤버 테이블을 조회하고 조회한 테이블에서 Team을 꺼내면
그 순간 데이터베이스에 등록된 Team의 칼럼 수 만큼 쿼리가 나간다. 만약 Team의 칼럼이 10000개가 있다면 하나를 조회하기 위해
쿼리가 10000+1번 나가는 것이다.
N+1은 1:N, 혹은 N:1 관계에서 발생한다.

  • 해결 방법
    • 즉시로딩( EAGER )은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어렵다.
    • 특히 JPQL을 실행할 때 N+1 문제가 자주 발생한다.
    • 실무에서 모든 연관관계는 지연로딩( LAZY )으로 설정해야 한다.
    • 연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용한다.
    • 만약 fetch join으로 풀리지 않는 관계가 있다면 Batch size를 조절하여 해결

참고

profile
하루 일지 보단 행동 고찰 과정에 대한 개발 블로그

0개의 댓글