EAGER VS LAZY
Eager(즉시 로딩) 방식
Eager(즉시 로딩) 방식을 사용하면 연관된 모든 값들을 가져온다.
따라서, 불필요한 정보, 중복 자료 등이 조회될 수 있으며, 어떤 쿼리가 추가적으로 발생하게 될지 예측하기 힘들다.
Lazy(지연 로딩) 방식
Lazy(지연 로딩) 방식을 사용하면 연관 엔티티가 사용될 때 해당 엔티티를 호출하게 되므로, 불필요한 조회를 막을 수 있다. 어떤 쿼리가 발생할지 비교적 예측이 쉬운 lazy 방식을 사용하자.
(EAGER 방식이 필요할 때가 있을지도 모른다. 그럼 그 때 또 알아 보자.)
N+1 이란?
1개의 쿼리로 조회한 엔티티와 연관관계를 맺고 있는 엔티티의 개수(N) 개 만큼 쿼리가 발생하는 문제이다.
언제 발생하는가?
jpa를 통해 DB에 쿼리를 날려 받은 결과값을 사용하려고 할 때
조회 시도한 엔티티와 연관관계에 있는 엔티티의 값이 확인되지 않으면
해당 값들을 조회하기 위해 DB에 쿼리를 날린다.
어떤 문제가 있는가?
조회한 엔티티와 관계 있는 엔티티가 10,000 개일 경우,
[최초 조회를 위한 쿼리] x 1개
[데이터가 확인되지 않는 연관관계 엔티티를 위한 쿼리] x N개
총 10,001 개의 쿼리가 발생한다.
쿼리가 많이 발생할수록 많은 비용이 발생하며, 성능 저하, DB 사망 등 다양한 문제로 이어질 수 있다.
어떻게 극복 하는가?
fetch join, entity graph , dto 등으로 극복 가능하다.
Fetch join
- 1차 쿼리를 날릴 때 연관관계에 놓인 엔티티까지 한꺼번에 조회하여, 엔티티 미확인으로 인한 N개의 쿼리 발생을 막는다.
Entity Graph
- Fetch join 과 동일하게 연관관계에 놓인 엔티티까지 한번에 조회하여, 엔티티 미확인으로 인한 N개의 쿼리 발생을 막는다.
- 연관관계 엔티티 로딩 방식을 사전에 정의해서 사용한다.
- 단, Entity Graph 의 경우, Outer Join 이 발생하기 때문에 Inner Join 으로 동작하는 Fetch join 보다 성능면에서 떨어진다.
Dto
- 연관관계 엔티티 없이 필요한 테이블만 조회할 때 사용한다.
- JpaRepository 인터페이스에서 메서드 반환 타입을 필요한 필드로만 구성된 Dto로하여 Dto에 값을 주입하므로 +N 쿼리 발생을 막는다.
- 단, EntityToDto() 로의 변환작업이 반드시 필요하게 되므로 성능면에서 좋지 않을 수 있다.
참조
https://programmer93.tistory.com/83
JPA N+1 문제 해결 방법 및 실무 적용 팁 - 삽질중인 개발자
- JPA N+1 문제 및 해결 방법 - JPA를 사용하다 보면 의도하지 않았지만 여러 번의 select 문이 순식간에 여러 개가 나가는 현상을 본 적이 있을 것이다. 이러한 현상을 N+1문제라고 부른다. 해당 포스
programmer93.tistory.com
https://ttl-blog.tistory.com/1135
[JPA] N+1 문제가 발생하는 여러 상황과 해결방법
🧐 N + 1 문제 N + 1 문제는 연관관계가 설정된 엔티티 사이에서 한 엔티티를 조회하였을 때, 조회된 엔티티의 개수(N 개)만큼 연관된 엔티티를 조회하기 위해 추가적인 쿼리가 발생하는 문제를 의
ttl-blog.tistory.com
실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발_엔티티 설계 시 주의점
학습 페이지
www.inflearn.com
틀린 내용, 부족한 내용 태클 환영합니다.
'스프링' 카테고리의 다른 글
| Log를 (기본만) 알아보자 (1) | 2023.05.16 |
|---|---|
| request 스코프 작성 (0) | 2023.04.07 |
| @Qualifier 단점 - 컴파일 단계에서 오류가 안 잡힘. (0) | 2023.04.06 |
| @Qualifier 단점 - 컴파일 단계에서 오류가 안 잡힘. (0) | 2023.03.31 |
| DI는 생성자 주입으로 하자 (1) | 2023.03.30 |
댓글