본문 바로가기

JPA

13.2.1 글로벌 페치 전략 수정

@Entity
public class Order {

   @Id @GeneratedValue
   private Long id;
   
   @ManyToOne(fetch = FetchType.EAGER) //즉시 로딩 전략
   private Member member; //주문회원
}

Order order = orderService.findOne(orderId);
Member member = order.getMember();
member.getName(); //이미 로딩된 엔티티

엔티티에 있는 fetch 타입을 변경하면 애플리케이션 전체에서 이 엔티티를 로딩할 때마다 해당전략을 사용하므오 글로벌 페치 전략이라 한다. FetchType.EAGER로 설정하고 엔티티 매니저로 주문 엔티티를 조회하면 연관된 member 엔티티도 항상 함께 로딩된다.

 

글로벌 페치 전략에 즉시 로딩 사용 시 단점

- 사용하지 않는 엔티티를 로딩한다.

- N+1 문제가 발생한다.

 

JPA를 사용하면서 성능상 가장 조심해야하는 것이 바로 N+1 문제다. N+1문제가 어떤 것인지 알아보자.

- em.find() 메소드로 엔티티를 조회할 때 연관된 엔티티를 로딩하는 전략이 즉시로딩이면 데이터 베이스에 JOIN 쿼리를 사용해서 한 번에 연관된 엔티티까지 조회한다. 하지만 JPQL을 사용할 때 문제가 발생한다.

 

JPA가 JPQL을 분석해서 SQL을 생성할 때는 글로벌 패치 전략을 참고하지 않고 오직 JPQL 자체만 사용한다. 따라서 즉시로딩이든 지연 로딩이든 구분하지 않고 JPQL쿼리 자체에 충실하게 SQL을 만든다. 

만약 조회한 order 엔티티가 10개이면 member를 조회하는 SQL도 10번 실행한다. 이처럼 처음 조회한 데이터 수만큼 다시 SQL을 사용해서 조회한 데이터 수만큼 다시 SQL을 사용해서 조회하는 것을 N+1문제라고 한다.

N+1이 발생하면 SQL이 상당히 많이 호출되므로 조회 성능에 치명적이다. -> JPQL페치 조인으로 해결가능하다.

'JPA' 카테고리의 다른 글

13.2.4 FACADE 계층 추가  (0) 2021.01.29
13.2.2 JPQL 페치조인  (0) 2021.01.29
13.1 트랜잭션 범위의 영속성 컨텍스트  (0) 2021.01.28
7.3.3 복합키 : 식별관계 매핑  (0) 2021.01.17
7.2 @MappedSuperClass  (0) 2021.01.17