느린 직렬화(Serialization) 과정 최적화하기

직렬화 과정의 병목을 찾아내고 해결하는 최적화 기법들로, 데이터베이스 쿼리는 빠르지만 JSON 변환 과정에서 발생하는 성능 저하를 해결

N+1 쿼리 해결

문제: 관련 객체 접근 시 매번 추가 쿼리 발생

  • Post 목록에서 각각의 author.username 접근 시 N+1 문제 발생

해결: select_relatedprefetch_related 활용

  • select_related: ForeignKey, OneToOneField 관계 (JOIN 사용)

  • prefetch_related: 역방향 ForeignKey, ManyToManyField 관계

# 개선 전
queryset = Post.objects.all()  # N+1 발생

# 개선 후  
queryset = Post.objects.select_related('author').all()  # 2번 쿼리로 해결

SerializerMethodField 최적화

문제: 커스텀 필드에서 매번 무거운 연산 실행

해결책 1: DB 레벨에서 미리 계산 (annotate)

# View에서 미리 계산
queryset = Post.objects.annotate(likes_count=Count('likes'))

# Serializer에서 일반 필드로 사용
likes_count = serializers.IntegerField(read_only=True)

해결책 2: 인스턴스 레벨 캐싱

목록/상세 Serializer 분리

목적: 목록 API에서 불필요한 데이터 제거로 응답 속도 향상

values()를 이용한 초고속 직렬화

목적: 대용량 데이터의 읽기 전용 API에서 극한 성능 필요 시

장점: 모델 인스턴스화 오버헤드 제거로 월등한 속도 단점: ModelSerializer 편의기능 사용 불가, 유지보수 어려움

최적화 우선순위

  1. select_related/prefetch_related: 모든 직렬화의 기본, N+1 의심 시 최우선 적용

  2. annotate: 집계/통계 데이터 필요 시

  3. Serializer 분리: 목록과 상세의 필요 데이터가 다를 때

  4. values() + Serializer: 대용량 읽기 전용 API에서 극한 성능 필요 시

Last updated