개발 과정에서 성능 최적화는 매우 중요한 과제 중 하나입니다. 특히, 대용량 데이터 처리 시, 데이터 조회 성능은 사용자 경험에 직접적인 영향을 미칩니다. 본 포스트에서는 시스템 로그 페이지 조회 성능을 개선한 사례를 공유하고자 합니다.
문제 상황
라이브 환경에서 시스템 로그 페이지 조회 시, 약 8.10초가 소요되는 문제가 발생했습니다. 조회 대상 데이터는 약 76,040건이었습니다.
문제 분석
ListView를 사용하는 클래스에서 전체 시스템 로그 데이터 갯수를 조회하는 과정에서 성능 저하가 발생했습니다. 특히, get_context_data 메서드에서 len(self.get_queryset())을 호출할 때 전체 테이블 데이터에 대한 조회 쿼리가 발생했습니다.
def get_context_data(self, **kwargs):
...
context['objects_count'] = len(self.get_queryset())
...
데이터베이스 로그를 확인해보니, limit 없이 system_log 테이블에 대한 전체 데이터 조회 쿼리가 두 번 전송되었습니다. 이로 인해 성능 저하가 발생했습니다.
len(self.get_queryset()) 대신 context['paginator'].count를 사용하는 방식으로 변경하여, Paginator 클래스의 count 속성을 사용했습니다. 이 방식은 전체 데이터 수를 조회할 때 데이터베이스에 쿼리를 날리지 않고, Paginator가 이미 계산한 결과를 사용합니다.
또한, get_queryset() 메서드에서 queryset에 대한 반복 처리 시, 쿼리셋이 평가되어 전체 데이터 조회 쿼리가 발생했습니다.
def get_queryset(self):
...
for query in queryset:
query.convert_log_data()
return queryset
이를 context의 object_list를 사용해 처리하도록 변경함으로써, ListView에서 지정한 paginated_by 값만큼만 처리되도록 개선했습니다. 이는 불필요한 전체 데이터 조회를 방지하고 성능을 향상시킵니다.
개선 결과
개선 전
- 소요 시간: 약 1분
개선 후
- 소요 시간: 0.7 밀리초
결론
이번 최적화 과정을 통해 데이터 조회 성능이 크게 향상되었습니다. Django의 Paginator 클래스와 쿼리셋의 평가 시점을 이해하고 적절히 활용함으로써, 대규모 데이터 처리 시 성능을 개선할 수 있음을 확인했습니다.
참고 자료
'프로그래밍' 카테고리의 다른 글
6초에서 0.2초로: 레거시 API 성능 개선 이야기 (0) | 2024.12.14 |
---|---|
번역 API 개선기: 번역 가능 언어 추가 요청을 받으며 배운 점 (0) | 2024.12.03 |
F-Lab 자바 백엔드 코스 멘토링 후기 (1) | 2023.12.03 |
MSW? (3) | 2023.11.23 |
REST API란? (0) | 2023.09.06 |