피드로 돌아가기
Dev.toDatabase
원문 읽기
SQL JOIN과 In-memory Merge를 통한 Django N+1 쿼리 문제 해결 및 쿼리 수 101회에서 1회로 단축
Optimizing Django ORM Queries: A Practical Guide to select_related and prefetch_related
AI 요약
Context
Django ORM의 Lazy Loading 특성으로 인한 N+1 쿼리 발생 및 이에 따른 데이터베이스 Round-trip 증가 문제. 데이터 규모 확대 시 런타임 성능이 급격히 저하되는 구조적 한계 존재.
Technical Solution
- ForeignKey 및 OneToOne 관계에서 SQL JOIN을 수행하는 select_related 도입을 통한 단일 쿼리 데이터 조회 구현
- ManyToMany 및 Reverse FK 관계에서 별도 쿼리 수행 후 Python 레벨에서 데이터를 병합하는 prefetch_related 적용
- Prefetch 캐시 무력화를 방지하기 위한 Prefetch 객체 기반의 필터링 로직 전이
- Wide JOIN으로 인한 네트워크 대역폭 낭비를 막기 위해 only() 메서드를 결합한 필요한 Column만 선택적 추출
- 복합 관계 조회를 위해 select_related와 prefetch_related를 체이닝하여 최적의 Fetch 전략 구성
Impact
- 100개 객체 조회 시 발생하는 101회의 쿼리를 1회(select_related) 또는 2회(prefetch_related)로 획기적 단축
실천 포인트
- ForeignKey/OneToOne 관계는 select_related를 통한 JOIN 처리 여부 확인 - ManyToMany/Reverse FK 관계는 prefetch_related를 통한 별도 Fetch 및 병합 적용 - Prefetched 쿼리셋에 추가 filter() 사용 시 캐시 우회 및 추가 쿼리 발생 가능성 검토 - django-debug-toolbar를 활용한 중복 쿼리 및 쿼리 횟수 실시간 모니터링