JPA
[JPA] N + 1 문제
감자b
2024. 12. 29. 02:47
N + 1 문제
N + 1 문제란 연관관계에서 발생하는 문제로 연관 관계가 설정된 엔티티를 조회할 때 조회된 데이터 갯수(n 개) 만큼 조회 쿼리가 추가로 발생하여 데이터를 읽어오는 것을 의미한다.
예를 들어 1개의 게시물에 10개의 댓글이 존재하고, 게시글과 댓글의 관계가 1 : N 관계일 때 해당 게시글을 조회하면 10개의 댓글에 대한 쿼리가 나가는 경우를 의미한다.
N+1이 발생하는 이유?
JPA는 메서드 이름을 분석한 뒤 JPQL을 생성하여 실행하게 된다. JPQL은 특정 SQL에 종속되지 않고 엔티티 객체와 필드 이름을 가지고 쿼리를 날리기 때문에 findAll()이란 메소드를 수행하였을 때 해당 엔티티를 조회하는 select * from board 쿼리만 실행하게 된다. 이후 결과를 받아 엔티티의 인스턴스를 생성하고, 연관된 엔티티 데이터가 필요한 경우, FetchType에 따라서 조회를 별도로 호출한다.
해결 방법
1. Fetch join
- JPQL로 “join fetch 엔티티.연관관계_엔티티” 구문으로 작성하면 Inner join을 통해 하나의 쿼리로 연관관계를 맺은 데이터를 모두 가져온다.
public interface BoardRepository extends JpaRepository<Board, Long> {
@Query("select b from Board b join fetch b.comments")
List<Board> findAllFetchJoin();
}
2. BatchSize
- application.yml에 글로벌 설정으로 default_batch_fetch_size: 100을 추가한다.
- default_batch_fetch_size란?
- 지연 로딩으로 설정한 컬렉션이나 프록시를 in 쿼리로 한 번에 가져오게 하는 설정으로, 이렇게 하면 지연 로딩으로 얻어온 댓글 리스트들이 매번 쿼리로 초기화 되는 것이 아니라 한 번에 in 쿼리로 조회가 된다.