본문 바로가기
C.W.K.
Stream
Lesson 04 of 10 · published

N+1 질의 문제

~14 min · operations, queries

Level 0스키마 새싹
0 XP0/86 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

목록 한 번 뒤에 항목 수만큼 더 묻는다

목록 1회로 사용자 100명을 읽고 1명당 관계 질의를 따로 보내면 1 + 100 = 101번 왕복해. 요청당 질의 수를 세어 봐. 5번이면 충분한 페이지가 500번을 실행한다면 N+1을 의심해야 해.

로그에서 반복을 찾아

Django Debug Toolbar, Rails Bullet, SQLAlchemy의 events처럼 요청당 질의를 세는 도구로 발견해. SQLAlchemy는 selectinload, Django는 prefetch_related, Rails는 includes로 관계를 미리 불러와.

JOIN·IN·집계로 고쳐

미리 불러오기로 두 번에 가져오거나 한 JOIN으로 합치고, 사용자별 개수만 필요하면 COUNT(*) ... GROUP BY user_id처럼 SQL에서 집계해.

Code

숨어 있는 N+1 질의·python
# N+1: user 1 쿼리, 그 다음 order N 쿼리
users = session.query(User).all()
for u in users:
    orders = u.orders  # ← 각 접근이 쿼리 발사
    print(u.name, len(orders))
미리 불러와 N+1 고치기·python
from sqlalchemy.orm import selectinload

users = session.query(User).options(selectinload(User.orders)).all()
for u in users:
    print(u.name, len(u.orders))  # 추가 쿼리 0
SQL 집계로 N+1 고치기·python
# 단일 쿼리: user + order count
rows = session.execute(
    text("""
      SELECT u.id, u.name, COUNT(o.id) AS order_count
      FROM users u
      LEFT JOIN orders o ON o.user_id = u.id
      GROUP BY u.id, u.name
    """)
).all()

External links

Exercise

프로젝트의 목록 화면 엔드포인트를 찾아 질의 기록을 켜고 요청 1번에 실행되는 질의 수를 세어. 5개가 넘으면 N+1 패턴이 있는지 확인하고 미리 불러오기나 직접 JOIN으로 고쳐.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.