본문 바로가기
Database2026년 6월 14일2분 읽기

N+1 쿼리 문제, 발견과 해결

YS
김영삼
조회 1052
N+1 쿼리 문제, 발견과 해결

핵심 요약

게시글 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

아직 댓글이 없습니다.
Ctrl+Enter로 등록