피드로 돌아가기
How I Caught and Fixed an N+1 Query in My Django REST API
Dev.toDev.to
Backend

N+1 Query 해결을 통해 API 요청당 61회 쿼리를 3회로 최적화

How I Caught and Fixed an N+1 Query in My Django REST API

Vicente G. Reyes2026년 5월 23일4intermediate

Context

Django ORM의 Lazy Loading 특성으로 인해 API 응답 시 관련 객체를 개별적으로 조회하는 N+1 Query 문제 발생. 데이터 증가에 따라 DB Hit 횟수가 선형적으로 증가하여 리스트 엔드포인트의 응답 속도가 저하되는 구조적 한계 노출.

Technical Solution

  • ForeignKey 및 OneToOne 관계인 'series' 필드에 select_related를 적용하여 SQL JOIN 기반의 단일 쿼리 조회 구현
  • ManyToMany 관계인 'tags' 필드에 prefetch_related를 도입하여 별도 쿼리 후 Python 레벨에서 캐싱 처리
  • Serializer에서 참조하는 모든 관계 필드를 QuerySet 레벨에서 Eager Loading 하도록 설계 변경
  • ViewSet의 기본 queryset뿐만 아니라 @action으로 정의된 개별 엔드포인트에도 동일한 최적화 로직 적용
  • django-debug-toolbar 및 nplusone 도구를 활용한 런타임 쿼리 수 모니터링 체계 구축

1. Nested Serializer 사용 시 해당 관계 필드가 QuerySet에 select_related 또는 prefetch_related로 포함되었는지 검토

2. PR 단계에서 ViewSet의 모든 쿼리 최적화 여부를 확인하는 체크리스트 운영

3. 개발 환경에 django-debug-toolbar를 설치하여 API 호출당 실제 실행되는 SQL 쿼리 수 상시 확인

원문 읽기