Spring Boot/JPA

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

공대생안씨 2023. 12. 28. 21:43

1. 즉시로딩

@ManyToOne (fetch = FetchType.EAGER)	// 즉시 로딩 전략
  • 엔티티를 조회할 때 연관된 엔티티도 모두 즉시 조회
  • ex) 멤버가 팀에 속하는 관계
    • 멤버 엔티티 조회할 때 팀 엔티티도 모두 조회됨
    • 즉, 멤버와 팀 관련 select 쿼리가 모두 DB에 전송됨
    • 이때 조회되는 팀은 프록시 객체가 아닌, Team 클래스
  • 다대일 (N:1), 일대일 (1:1) 연관관계는 즉시로딩이 기본값

 

2. 지연로딩

@ManyToOne(fetch = FetchType.LAZY)	// 지연 로딩 전략
  • 엔티티를 조회할 때 연관된 엔티티는 프록시로 조회하고 실제 사용하는 시점에 초기화 됨 (DB 조회)
  • ex) 멤버가 팀에 속하는 관계
    • 멤버 엔티티 조회할 때 팀 엔티티는 조회되지 않음 (멤버 : DB에서 조회 / 팀 : 프록시 타입으로 조회)
    • 멤버와 관련된 select 쿼리만 전송됨
    • 이때 팀은 프록시 객체로 가지고 있으며 실제 팀을 사용하는 시점에 초기화 (이때 DB에 쿼리 전송됨)
  • 일대다 (1:N), 다대다 (N:M) 연관관계는 지연로딩이 기본값

 

3. 지연로딩 사용

// x:1 (다대일 혹은 일대일) 의 연관관계는 반드시 지연 로딩으로 설정!
@ManyToOne(fetch = FetchType.LAZY)
@OneToOne(fetch = FetchType.LAZY)
  • 만약 다대일 (N:1) 이나 일대일 (1:1) 의 연관관계 일 때 즉시로딩을 사용하면 N+1 문제를 일으킴
    • N+1 문제
      • 즉시 로딩 => 조회하려는 엔티티는 한 개인데 그와 연관된 N개의 엔티티를 모두 조회함
      • DB에 전송되는 쿼리 개수 = 1 (조회하려는 엔티티 조회 쿼리) + N (연관된 엔티티 조회 쿼리)
      • 즉, 1개만 의도한 쿼리가 N+1 개의 쿼리로 전송되어서 성능 저하로 이어질 수 있음!
  • 다대일, 일대일은 즉시 로딩이 기본값이므로 모두 지연로딩으로 설정
    • 즉시 로딩과 같이 한 번에 조회하기를 원하면 JPQL의 fetch 조인으로 해결!