Coding 01

JPA의 N + 1 문제 본문

기술면접

JPA의 N + 1 문제

하루우울루 2024. 12. 2. 18:15

JPA에는 N + 1이라는 성능 문제가 있다. 테이블의 연관 관계에서 발생하는 문제로, 최초 1번의 쿼리로 N개의 데이터를 가져온 후, 연관된 데이터를 가져오기 위해 N번의 추가 쿼리가 발생하는 현상이다.

 

N + 1문제는 연관관계가 있는 Entity를 조회할 때 발생하는 문제이고, 발생하는 조건을 정리해보면 다음과 같다.

 

1. 지연로딩(LAZY) 설정이 되어있는 연관관계가 있을 경우

2. 연관된 데이터를 실제로 사용하는 시점에서

3. 별도의 최적화 처리를 하지 않은 경우


예제를 통해 N + 1문제를 알아보자.

Team과 Member의 관계를 보고 설명을 하자면,

Entity
문제가 발생하는 경우

 

이 서비스 코드에서 findAll()메서드에서 N + 1문제가 발생한다.

메서드에서 select * from team; 쿼리가 실행되고, 이때

 

각 팀에 대한 멤버를 조회하는 N번의 조회 쿼리가 발생하게 된다.

select * from member where team_id = ?;

select * from member where team_id = ?;

select * from member where team_id = ?; 

=== > N번 반복

 

이 문제로 인해 데이터베이스 쿼리가 불필요하게 많이 실행되고, 그로인한 부하, 네트워크 트래픽도 증가될 수 있는 문제가 있을 수 있다.


N + 1문제는 findAll()메서드에서만 국한된 것이 아니라 findById, findByName과 같은 조회 메서드에서도 발생 할 수 있다.

N+1 문제 발생 상황


N + 1 문제를 해결하기 위한 해결책으로는 다음과 같다.

 

Fetch Join

가장 일반적인 해결책이지만 페이징이 불가능하다는 문제가 있다.

oneToMany관계에서 데이터 row가 증가하여 정확한 페이징 처리가 안된다.

여러 관계를 한번에 fetch join을 하면 성능이 저하된다.

중복 데이터에 관해 조심해야 한다.

BatchSize

IN절의 갯수를 적절히 설정해야 한다.

추가 쿼리가 발생하기 때문에 완벽한 해결책은 아니다.

EntityGraph

불피요한 컬럼까지 모두 조회해서 데이터 전송량이 증가될 수 있다.

연관 관계가 복잡한 경우 성능이 저하될 수 있다.