SerializerMethodField의 성능 함정과 캐싱으로 해결하기

SerializerMethodField는 유연하지만 리스트 조회 시 N+1 쿼리 문제를 발생시킴. 이를 Serializer 레벨 캐싱이나 ORM 최적화로 해결 가능

SerializerMethodField란

  • 여러 모델 필드를 조합하여 새로운 값을 만들 때 사용

  • 모델에 없는 계산된 값을 포함시킬 때 사용

  • 관계된 객체의 특정 값을 가공해서 표시할 때 사용

성능 함정: N+1 쿼리 문제

  • 게시글 목록 조회 시 각 게시글마다 작성자 정보를 가져오기 위해 추가 쿼리 발생

  • 100개 게시글이 있으면 총 101번의 쿼리 실행 (1번 + 100번)

  • API 응답 시간이 급격히 느려짐

해결책 1: Serializer 레벨 캐싱

동작 원리

  • __init__에서 직렬화할 모든 객체의 필요한 ID 추출

  • in_bulk로 관련 데이터를 한 번에 조회하여 캐시에 저장

  • get_... 메서드에서 DB 쿼리 대신 캐시 참조

결과: 게시글 개수와 관계없이 2번의 쿼리로 고정

해결책 2: ORM 최적화

동작 원리

  • View의 queryset에서 select_related 사용하여 미리 JOIN

  • Serializer에서 source 속성으로 관계 필드에 직접 접근

  • SerializerMethodField 없이 단순하게 처리

결과: 1번의 JOIN 쿼리로 모든 데이터 조회

어떤 방법을 선택할까

구분
Serializer 캐싱
ORM 최적화

적용 상황

복잡한 계산, 외부 API 호출

단순한 관계 필드 조회

성능

매우 좋음 (2회 쿼리)

최상 (1회 쿼리)

코드 복잡도

높음

낮음

핵심 원칙

  • SerializerMethodField 사용 전 ORM으로 해결 가능한지 먼저 검토

  • 프로파일링 도구로 병목 지점 확인 후 최적화 진행

  • 단순한 관계 필드는 ORM 최적화, 복잡한 로직은 캐싱 활용

Last updated