[Spring] 지연 로딩, 즉시 로딩

이연우·2025년 8월 19일

TIL

목록 보기
88/100

💤 Lazy Loading (지연 로딩)이란?

  • 데이터를 실제 사용할 때만 DB에서 조회하는 방식

🚀 설정 방법:

@ManyToOne(fetch = FetchType.LAZY)
private Company company;

🎭 특징:

  • 처음에는 Proxy 객체(가짜 엔티티)로 조회됨
  • 실제 값 접근 시(getCompany().getName()) → 그 순간 SQL 실행
  • 불필요한 JOIN 방지 → 성능 최적화

⚡ 언제 쓰나?

  • 연관된 엔티티를 자주 쓰지 않는 경우
  • 필요할 때만 불러오는 게 효율적인 경우

🔎 Lazy Loading 실행 흐름

  1. Tutor 조회 시 Company는 Proxy로 반환
  2. getCompany() 호출 시 Proxy 객체 확인 가능
  3. getCompany().getName() 접근 순간 SQL 실행 → Company 초기화

👉 결과: 필요한 순간에만 DB 조회


⚡ Eager Loading (즉시 로딩)이란?

  • 엔티티를 조회할 때 연관된 데이터까지 모두 한 번에 로드하는 방식

🚀 설정 방법:

@ManyToOne(fetch = FetchType.EAGER)
private Company company;

🎭 특징:

  • Tutor 조회 시 Company즉시 JOIN 해서 함께 조회
  • Proxy 객체가 아닌 실제 엔티티 반환
  • 매번 연관된 엔티티까지 필요한 경우 적합

⚡ 언제 쓰나?

  • 연관 엔티티를 항상 사용하는 경우
  • JOIN이 더 효율적인 경우

🚨 즉시 로딩 주의점

1. 예상치 못한 SQL 실행 → 불필요한 JOIN 발생 ❌

2. N+1 문제 발생 ⚠️

  • JPQL 실행 시
    • 처음 쿼리 1번(Tutor 전체 조회)
    • 연관된 엔티티 N번(Company N개 조회)
  • 결과: 총 N+1번 쿼리 실행 → 성능 저하

3. 기본 fetch 전략 차이:

  • @OneToMany, @ManyToMany → 기본값: LAZY
  • @ManyToOne, @OneToOne → 기본값: EAGER
    → 반드시 LAZY로 바꿔 쓰는 게 안전 👍

🛠️ N+1 문제 해결 방법

  • 모든 연관관계는 기본적으로 LAZY 사용 권장 ✅
  • 필요할 때만 아래 방법으로 최적화:
    1. Fetch Join (JPQL) → 가장 많이 사용
      select t from Tutor t join fetch t.company
    2. @EntityGraph
    3. @BatchSize
    4. Native Query

🧠 요약 정리

구분Lazy Loading 💤Eager Loading ⚡
DB 조회 시점실제 값에 접근할 때엔티티 조회 시 즉시
조회 객체Proxy 객체(가짜) 🎭실제 엔티티
SQL 실행 방식필요한 시점마다 실행JOIN으로 한 번에 실행
장점불필요한 쿼리 방지, 성능 최적화항상 함께 조회 시 편리
단점준영속 상태 접근 시 예외 ⚠️예상 못한 JOIN, N+1 문제 발생
적합한 경우연관 객체를 가끔 사용할 때연관 객체를 항상 사용할 때

0개의 댓글