핵심 요약
게시글 10개를 가져온 뒤 각 글의 작성자를 따로 조회하면 1+10번 쿼리가 나간다 — 이게 N+1이다. ORM의 eager loading(include/join)이나 IN 절 일괄 조회, GraphQL이면 DataLoader로 묶어 쿼리 수를 1~2개로 줄인다.
1. 발견
- ORM 쿼리 로깅을 켜고 한 화면에 같은 쿼리가 N번 반복되는지 본다
- APM(요청당 쿼리 수)으로도 잡힌다
2. 해결
// ❌ N+1
const posts = await Post.findAll()
for (const p of posts) p.author = await User.find(p.authorId)
// ✅ eager loading (한 번에)
const posts = await Post.findAll({ include: [User] })
// 또는 authorId 모아서 IN 절로 한 번
3. 함정
- 과한 eager loading은 거대한 조인·중복 행을 만든다 — 필요한 관계만
- 중첩 관계(글→댓글→작성자)는 단계별로 묶어야 한다
- 페이지네이션과 조인을 함께 쓰면 LIMIT가 조인 후 적용돼 행 수가 어긋날 수 있다
자주 묻는 질문
ORM을 쓰는데도 N+1이 생기나요?
오히려 ORM에서 흔합니다. 관계 접근이 지연 로딩이면 반복문 안에서 매번 쿼리가 나갑니다. include/join을 명시하거나 일괄 조회로 바꾸세요.
전부 eager loading하면 되나요?
필요 없는 관계까지 끌어오면 데이터·조인이 과해져 느려집니다. 화면에 실제로 쓰는 관계만 선택적으로 로딩하세요.

댓글 0