[JPA] 지연 로딩(Lazy Loading)과 즉시 로딩(Eager Loading)

JPA에서는 연관된 엔티티를 가져오는 방법으로 지연 로딩과 즉시 로딩이 있다.

 

지연 로딩

지연 로딩은 연관된 엔티티를 사용할 때까지 로딩을 지연하는 방식이다.

지연 로딩을 사용함으로써 연관 엔티티의 데이터를 사용할 필요가 없는 경우, 쿼리 수행과 시간을 절약할 수 있다.

@xxToxx(fetch = fetchType.LAZY)

 

언제 지연로딩을 사용할까?
  1. 연관 엔티티를 많이 사용하지 않는 경우
    부모 객체를 조회할 때 자식 객체를 따로 조회하지 않고, 자식 객체가 필요한 경우만 로드하여 사용할 때 유용하다.
  2. 실제로 필요한 경우에만 연관 엔티티를 사용하는 경우
    연관 엔티티가 필요한 경우에만 로딩하여 불필요한 쿼리가 수행되지 않아, 쿼리 수행 시간을 줄일 수 있다.
  3. 대용량 데이터 처리
    연관된 엔티티를 무조건 로드하지 않아 불필요한 메모리 사용량을 줄일 수 있다. (특히 대용량 데이터 환경)
  4. 성능 최적화가 필요한 경우
    필요한 경우에만 연관 엔티티를 로딩할 수 있도록 지연 로딩을 사용하여 성능을 최적화할 수 있다.

 


즉시 로딩

즉시 로딩은 연관된 엔티티를 함께 로딩하는 방식이다.

연관 엔티티를 미리 로딩하여 객체가 사용되기 전에 필요한 데이터를 미리 준비하여, 기본 엔티티를 로딩할 때 연관된 엔티티도 함께 조회한다.

@xxToxx(fetch = fetchType.EAGER)

 

언제 즉시 로딩을 사용할까?
  1. 자주 사용되는 연관 엔티티일 때
    자주 사용되는 연관 엔티티의 경우에는 미리 로딩하여 사용한다면 쿼리 수행 시간이 감소하므로 유용하다.
  2. 연관 엔티티의 크기가 작을 때
    연관 엔티티의 크기가 작은 경우에는 미리 로딩하여 사용한다면 메모리 효율을 높일 수 있다.

즉시 로딩을 과도하게 사용하면 모든 쿼리 결과를 로딩하므로, 모든 데이터에 대해 사용하면 디스크 I/O 및 메모리 사용량이 높아지며 성능 저하 문제가 발생할 수 있다.

가급적이면 지연 로딩을 사용하는 것을 권장한다.


N + 1 문제

N+1 문제는 연관 엔티티가 실제 사용될 때마다 별도의 쿼리가 발생하여 성능 이슈를 초래하는 것이다.

즉시 로딩과 지연 로딩 모두 N + 1 문제가 발생할 수 있다.

 

예를 들어 주문(Order)과 상품(Product) 엔티티가 있다고 가정해보자, 각 주문에는 여러 상품이 있을 수 있다. ( 일 대 다 )

  1. 먼저 모든 주문(Order)을 쿼리 (1번의 쿼리).
  2. 각 주문과 연관된 상품(Product)을 구하기 위해 각 주문마다 추가적인 쿼리를 수행 (N번의 쿼리).

즉 결과적으로, 주문 수가 N개인 경우, 총 N+1개의 쿼리가 발생하게 된다.

이렇게 중복된 쿼리가 발생하면 성능 저하가 발생할 수 있다.

 

해결 방법

연관된 엔티티를 원하는 엔티티와 함께 한 번의 쿼리로 가져오도록  패치 조인(Fetch Join)을 사용해 N+1 문제를 해결할 수 있다.

 

[JPA] JPQL의 fetch join(페치 조인)이란?

JPQL에서 성능 최적화를 위해 제공하는 기능 연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회 하는 기능 Lazy loading + fetch join을 권장드리는 이유는 본질적으로 필요할 때만 같이 불러오기 위해서

hstory0208.tistory.com