N+1 문제의 발생 이유와 해결 방법에 대해 설명해주실 수 있을까요? 해결 방법은 3가지 이상 말씀해주시면 좋습니다.
N+1 문제란?
N+1 문제는 데이터베이스 쿼리를 실행할 때 발생할 수 있는 성능 문제 중 하나로, 쿼리 실행 시 추가적인 N개의 쿼리가 발생하여 성능저하를 초래할 수 있습니다.
이는 주로 ORM(Object-Relation Mapping)를 사용하는 경우 발생하며, 한 번의 부모 쿼리로 N개의 자식 쿼리를 가져오는 방식에서 문제가 발생합니다.
Lazy Loading(지연 로딩) : 연관된 데이터가 실제로 필요할때만 로드되도록 설계된 방식이지만, 이를 잘못 사용할 경우 여러번의 쿼리가 발생하여 N+1 문제가 발생할 수 있습니다.
Eager Loading(즉시 로딩) : Eager 전략으로 데이터를 조회하는 경우 N+1 문제가 발생할 수 있습니다.
Eager(즉시 로딩)인 경우
- JPQL에서 만든 SQL을 통해 데이터를 조회
- 이후 JPA에서 Fetch 전략을 가지고 해당 데이터의 연관 관계인 하위엔티티를 추가 조회시 N+1 문제 발생
Lazy(지연 로딩)인 경우
- JPQL에서 만든 SQL을 통해 데이터를 조회
- JPA에서 Fetch 전략을 가지지만, 지연 로딩이기 때문에 추가 조회는 하지 않음
- 하지만, 하위 엔티티를 가지고 작업하게 되면 추가 조회가 발생하기 때문에 결국 N+1 문제가 발생하게 된다.
해결방법
- Join Fetch 사용 : 조인을 통해 필요한 모든 데이터를 한 번에 가져오는 방식으로 문제를 해결할 수 있습니다.
- 캐싱 사용 : 자주 사용되는 데이터를 캐싱하여 데이터베이스 쿼리 횟수를 줄여 성능을 향상시킬 수 있습니다.
- Batch Fetching 사용 : 데이터베이스에 배치 쿼리를 보내 여러 엔티티를 한 번에 가져오는 방식으로 성능을 향상 시킬 수 있습니다.
N+1문제란 1번의 쿼리를 날렸을 때 의도하지 않은 N번의 쿼리가 추가적으로 실행되는 것을 의미하며 Jpa Repository를 활용해 인터페이스 메소드를 호출할 때 1:N또는 N:1 관계를 가진 엔티티를 조회할 때 발생합니다. 즉시로딩인 경우 JPQL에서 만든 SQL을 통해 데이터 조회 시 Fetch 전략을 가지고 해당 데이터의 연관 관계인 하위 엔티티들을 추가로 조회할 때 발생하게 되고, 지연로딩인 경우 조회 시 Fetch 전략을 가지지만 추가 조회는 하지 않지만 하위 엔티티를 가지고 작업을 하게 되면 추가 조회가 발생하기 때문에 결국 N+1 문제가 발생하게 됩니다. N+1의 해결방법은 Join Fetch 사용하거나, 캐싱을 사용하거나, Batch Fetching 사용하여 문제를 해결 할 수 있습니다. Join Fetch는 Join을 통해 필요한 모든 데이터를 한 번에 가져오는 방식으로 문제를 해결 할 수있으며 자주 사용되는 데이터를 캐싱하여 데이터베이스 쿼리 횟수를 줄여 성능을 향상시킬 수 있습니다. 마지막으로 데이터베이스에 배치 쿼리를 보내 여러 엔티티를 한 번에 가져오는 방식을 성능을 향상 시킬 수 있습니다.
Reference
'CS' 카테고리의 다른 글
기본키(Primary Key), 외래키(Foreign Key) (1) | 2024.01.01 |
---|---|
HTTP Method (1) | 2024.01.01 |
SpringSecurity와 인증, 인가, JWT의 구조, 동작 과정 (1) | 2023.12.27 |
Web Server & WAS (0) | 2023.12.23 |
MVC 모델이란 (0) | 2023.12.21 |