현재는 Where In 절을 사용하는 Batch Fetching 방식을 선호한다.
N+1문제는 1:N or N:1 관계에서 발생하는 문제로 1번의 쿼리를 보냈지만 N번의 쿼리가 더 발생하는 문제다.
외래키에 해당하는 하위 엔티티를 하나씩 조회하므로 N번 더 쿼리를 보내게 된다.
해결방법으론 Fetch Join, Entity Graph 두가지가 있다.
Fetch Join
@Query("select DISTINCT b from Board b join fetch b.likesList")
List<Board> findAllFetchJoin();
Entity Graph
@EntityGraph(attributePaths = {"likesList"})
@Query("select DISTINCT b from Board b")
List<Board> findAllEntityGraph(Sort sort);
Fetch Join은 1:N 관계가 두개 이상인 경우, Paging API를 사용할 경우 에는 사용할 수 없다는 단점이 있다.
Query문에 있는 DISINCT는 중복을 제거해주는 SQL문이다.
만약 Select에 2개 이상의 테이블이 들어간다면 모두 묶어서 중복을 체크하니 사용에 주의해야 한다.
DISINCT를 사용하는 이유는 카테시안 곱을 발생시키지 않기 위해서다.
카테시안 곱 : 두 테이블간 모든 데이터를 결합시켜서 두 행의 갯수를 곱한만큼 결과가 반환된다. where절에 적절한 join조건을 넣지 않았거나 아예 없는 경우에 발생한다.
'JAVA > Spring Boot' 카테고리의 다른 글
[Validation] 누락된 값 전역 처리, 클라이언트에 상세히 표시 (0) | 2023.01.25 |
---|---|
Spring Boot, Gradle 멀티 모듈 프로젝트 실전 예제 (0) | 2022.12.28 |
jwt 정리 잘 된 블로그 메모 (0) | 2022.07.13 |
JPA) 특정 컬럼 제외하고 반환하기 (0) | 2022.06.06 |
JPA) ManyToOne 양방향 관계 설정 (0) | 2022.06.05 |