n+1 문제
2024. 11. 22. 19:10ㆍ컴퓨터언어/Database
728x90
반응형
n+1 문제는 데이터베이스 쿼리 최적화와 관련된 성능 문제로, 주로 ORM(Object Relational Mapping) 프레임워크에서 발생한다.
간단히 말하면, 한 번에 해결할 수 있는 작업을 불필요하게 여러 번 쿼리하는 문제다.
기본 개념
n+1 쿼리는 특정 객체를 가져오고 관련된 객체를 로드할 때,
- 1개의 메인 쿼리로 상위 데이터를 가져온 후,
- n개의 추가 쿼리로 관련 데이터를 각각 개별적으로 가져오는 경우를 말한다.
이로 인해 필요 이상으로 많은 데이터베이스 호출이 발생하게 되고, 성능 저하를 초래한다.
예제
게시글과 댓글이 1:N 관계에 있다고 가정하자.
그리고 게시글 리스트를 조회하면서 각 게시글에 달린 댓글도 가져오려는 경우를 생각해보자.
이때 n+1 쿼리가 발생할 수 있다.
-- 1개의 메인 쿼리로 모든 게시글을 가져옴
SELECT * FROM posts;
-- 게시글 수만큼 추가로 댓글을 가져오는 n개의 쿼리 실행
SELECT * FROM comments WHERE post_id = 1;
SELECT * FROM comments WHERE post_id = 2;
...
SELECT * FROM comments WHERE post_id = n;
게시글이 100개라면 총 1 + 100 = 101번의 쿼리가 실행된다.
해결 방법
1. Eager Loading (즉시 로딩)
필요한 데이터를 한 번의 쿼리로 모두 가져온다.
SELECT posts.*, comments.*
FROM posts
LEFT JOIN comments ON posts.id = comments.post_id;
JOIN으로 게시글과 댓글을 한 번에 가져오자.
2. Batch Loading (배치 로딩)
관련 데이터를 한 번에 묶어 가져온다.
SELECT * FROM comments WHERE post_id IN (1, 2, 3, ..., n);
상위 데이터를 조회한 후 필요한 하위 데이터를 한 번에 로드하자.
3. Lazy Loading (지연 로딩)
관련 데이터가 실제로 필요할 때만 데이터를 가져오자.
단, 잘못 사용하면 n+1 문제를 유발할 수 있으므로 주의가 필요하다.
728x90
반응형
'컴퓨터언어 > Database' 카테고리의 다른 글
Expressions with $project (0) | 2021.02.04 |
---|---|
Chapter 1: Basic Aggregation - $match and $project (0) | 2021.02.03 |
max_user_connection 초과라고? 내 코드에 문제가 있는 거 아닐까? (0) | 2021.02.01 |
[MongoDB University] 정리 (0) | 2021.02.01 |
[반정규화] 테이블 분할의 단점 (Feat. 정규화vs반정규화) (0) | 2020.08.03 |