Zayson
A to Zayson!
Zayson
전체 방문자
오늘
어제
  • 분류 전체보기 (132)
    • Computer Science (20)
      • Network (4)
      • DB (12)
      • OS (4)
    • Algorithm (32)
      • 완전탐색(Brute-Force) (3)
      • 그리디(Greedy) (6)
      • 투포인터(Two-Pointer) (1)
      • 그래프(Graph) (5)
      • BFS & DFS (9)
      • 구현, 시뮬레이션(Implementation) (5)
      • 다이나믹 프로그래밍(DP) (3)
    • Backend (51)
      • Spring Boot (19)
      • JPA (16)
      • Kafka (2)
      • Java (13)
      • Kotlin (1)
    • DevOps (1)
      • Jenkins (5)
      • Oracle Cloud Infrastructure (1)
      • Kubernetes & Docker (1)
    • Trouble Shooting (3)
      • JPA (1)
      • Spring Boot (2)
    • 회고 (5)
      • 엔빵 프로젝트 포스트 로드맵 (1)
      • 2022년 (4)
    • Kafka (7)
      • Kafka (5)
      • Kafka Connect (2)
    • 기술 서적 (6)
      • 데이터 중심 애플리케이션 설계 (3)
      • 개발자가 반드시 정복해야할 객체 지향과 디자인 패턴 (2)
      • 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

  • JPA
  • 관계형 데이터베이스 실전 입문
  • Java
  • 엔빵프로젝트
  • kafka
  • SpringBoot
  • BFS
  • spring boot
  • 프로그래머스
  • 백준
  • 완전탐색
  • Kafka Connect
  • 라이브스터디
  • dfs
  • 나 혼자 스프링부트!
  • 그리디
  • 구현
  • Backend
  • Computer science
  • CS

최근 글

티스토리

hELLO · Designed By 정상우.
Zayson

A to Zayson!

즉시 로딩과 지연 로딩
Backend/JPA

즉시 로딩과 지연 로딩

2022. 7. 21. 15:29
  • 지연 로딩을 통해 연관관계 데이터를 실제 조회 시점에 가져오는 것이 가능하다.
  • fetch = FetchType.LAZY
@ManyToOne(fetch = FetchType.LAZY)  // 지연 로딩으로 세팅
@JoinColumn(name = "TEAM_ID")   
private Team team;

 

  • 연관 관계 엔티티를 지연 로딩으로 세팅하면 프록시로 가져온다.
  • 지연 로딩으로 가져온 엔티티는 실제 값을 사용하는 시점에 프록시를 초기화한다.
Member member1 = new Member();
member1.setUsername("zayson1");
member1.setTeam(team);

// Team의 데이터는 프록시로 가져온다. (Team 조회 쿼리 안날아감)
Member member = em.find(Member.class, member1.getId());

// 실제 Team을 사용하는 시점에 프록시를 초기화한다. (Team 조회 쿼리 날아감)
System.out.println("member.getTeam().getName() = " + member.getTeam().getName());

 

  • 연관관계를 함께 조회하는 경우가 많은 경우는 즉시 로딩을 사용할 수 있다.
  • fetch = FetchType.EAGER
  • 즉시 로딩으로 설정한 연관 관계 엔티티는 조인이되어 한번에 조회가 된다.

 

  • 한번에 데이터를 조회해 오기 때문에 프록시 객체로 연관 관계를 가져올 필요가 없다. 따라서, 즉시 로딩된 연관관계 엔티티는 실제 클래스 타입이다.

 

🚨 실무에서는 즉시 로딩을 사용을 지양한다.

✔️ 즉시 로딩을 이용하는 경우 예상하지 못한 SQL이 발생할 수 있다.

  • 즉시 로딩이 된 테이블이 1-2개면 체감이 안되지만, 실무에서는 테이블이 여러개이고 여러개가 즉시로딩 되어있다면 여러개의 테이블을 모두 조인해서 가져온다!!

✔️ 즉시 로딩은 JPQL에서 N+1 문제를 발생시킨다.

  • 회원 데이터가 10개인 경우 연관관계인 Team 데이터를 조회하기 위해 10번의 쿼리가 추가적으로 발생한다.
  • 회원 데이터 조회 쿼리 (1) + 회원 10명에 대한 Team 정보 조회 (10) = N + 1 문제
SELECT * FROM MEMBER; // 1번 -> 결과 : 10 row
SELECT * FROM TEAM WHERE MEMBER_ID = (1-10); // 10번의 쿼리 발생

💡 N + 1 문제 해결법

  1. 모든 연관 관계는 지연 로딩을 기본으로 한다.
  2. Fetch Join이나 엔티티 그래프 기능을 이용해 데이터를 조회한다.
  3. BatchSize를 지정한다.

✔️ @XtoOne 관계는 default가 즉시 로딩이기 때문에 지연 로딩으로 변경한다.

 

📄 References

김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 : https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

반응형
저작자표시 비영리 변경금지 (새창열림)

'Backend > JPA' 카테고리의 다른 글

값 타입  (0) 2022.07.26
영속성 전이 (Cascade), 고아 객체  (0) 2022.07.21
프록시  (0) 2022.07.20
상속관계 매핑  (0) 2022.07.20
엔티티 설계의 주의사항 간단 정리  (0) 2022.07.05
    'Backend/JPA' 카테고리의 다른 글
    • 값 타입
    • 영속성 전이 (Cascade), 고아 객체
    • 프록시
    • 상속관계 매핑
    Zayson
    Zayson
    공부한 내용을 정리하는 공간

    티스토리툴바