피드로 돌아가기
Dev.toDatabase
원문 읽기
701개 쿼리를 3개로 단축한 Django ORM N+1 Query 최적화 전략
The N+1 Query Problem That's Silently Slowing Your Django App
AI 요약
Context
Lazy Loading 기반의 Django ORM 특성으로 인해 Template 렌더링 시 연관 객체에 반복 접근하며 발생하는 N+1 Query 문제 분석. 로컬 환경의 적은 데이터셋으로 인해 발견되지 않다가 Production의 대규모 데이터셋에서 DB CPU 부하 및 응답 시간 지연을 유발하는 구조적 한계점 확인.
Technical Solution
- ForeignKey 및 OneToOneField 관계에 대해 SQL JOIN을 생성하는 select_related 도입으로 단일 쿼리 내 데이터 fetch 구현
- ManyToManyField 및 역참조 관계를 처리하기 위해 별도 쿼리 실행 후 Python 메모리상에서 조인하는 prefetch_related 적용
- Prefetch 객체와 Custom Queryset을 활용하여 Loop 내 필터링으로 인한 Prefetch 무효화 방지 및 쿼리 재발생 차단
- django-debug-toolbar를 통한 Request당 쿼리 수 모니터링 체계 구축으로 SQL 실행 패턴 가시화
- assertNumQueries 기반의 테스트 코드를 CI 파이프라인에 통합하여 N+1 Query 회귀 가능성을 원천 봉쇄하는 검증 구조 설계
실천 포인트
- Template 내에서 .all() 또는 연관 필드 접근 시 select_related/prefetch_related 적용 여부 검토 - 관계 필드 필터링 필요 시 Loop 내 filter() 대신 Prefetch 객체 사용 여부 확인 - 신규 API/페이지 개발 시 django-debug-toolbar를 통해 쿼리 수가 10개 이하로 유지되는지 검증 - 핵심 경로의 View에 대해 assertNumQueries를 포함한 쿼리 수 제한 테스트 코드 작성