[상품 썸네일 배지 성능 개선기] 1.초당 4,000건의 호출을 200건으로 줄인 이야기
첨부된 이미지의 좌상단과 하단에 있는 배지가 보이시나요? 이번 글의 주인공입니다!
최근, 상품 썸네일에 부착되는 배지 기능이 다양한 영역에서 호출되며 심각한 성능 저하를 유발하고 있다는 사실을 발견했습니다. 이를 계기로 쿼리 튜닝, 인덱스 재설계, 조회 로직 개선 등을 수행하여 초당 호출 수 95% 감소라는 성과를 달성하게 되었습니다.
이번 글에서는 어떤 문제가 있었고, 어떻게 해결했는지 기술 중심으로 정리해보겠습니다.
🧨 문제 상황
상품에 대표 배지를 2개씩 부착하는 로직은 다음과 같은 페이지들에서 공통으로 호출되고 있었습니다.
- 기획전
- 상품 목록
- 상품 상세 페이지
- etc
하지만, 각 위치에서 매번 별도의 조회를 수행하고 있었고, 다음과 같은 문제가 발생했습니다.
🔍 상세 지표
항목 | 수치 |
---|---|
초당 배지 쿼리 호출 수 | 약 4,000회 |
호출 1회당 row 스캔 수 | 약 4,200건 |
총 스캔 수 (초당) | 약 16,800,000 row |
단일 쿼리임에도 데이터가 너무 자주 호출되고 있고, 그 쿼리 하나로 초당 약 1,680만 건의 row가 스캔되고 있다는 점에서 DB 커넥션 오류 및 시스템 부하가 우려되는 상황이었습니다.
개선 전략
문제를 해결하기 위해 아래와 같이 쿼리 최적화 + 호출 구조 개선을 병행했습니다.
1. 쿼리 튜닝: 불필요 조건 제거 및 인덱스 재설계
- 기존 쿼리:
WHERE 컬럼1 + 컬럼2 + 컬럼3 order by 컬럼4 desc
(컬럼1은 제거가능, 컬럼4는 정렬로 사용되나, 실제로는 정렬이 필요 없었음) - 개선 쿼리:
WHERE 컬럼2 + 컬럼3
- 복합 인덱스 개선:
컬럼1 + 컬럼2 + 컬럼3 order by 컬럼4 desc
→컬럼2 + 컬럼3
인덱스로 단순화
🎯 효과
- 호출당 row 스캔 수:
4,200건 → 약 10건
으로 대폭 감소
2. 로직 개선: 배지 포지션별 개별 조회 → 일괄 조회
- 기존에는 배지 1개 조회 시 쿼리 1회 수행 → 상품당 2회 호출
- 배지 수는 고정(2개)이므로 한 번에 전체 조회 후 포지션을 로직으로 구분
🎯 효과
- 초당 쿼리 호출 수:
4,000회 → 약 200회
- 총 쿼리량 기준 약 95% 감소
📊 개선 결과
개선 전후를 모니터링한 결과 다음과 같은 수치를 확인할 수 있었습니다.
시점 | 초당 최대 호출 수 |
---|---|
개선 전 | 약 1,800회 |
개선 후 | 약 200회 |
쿼리 튜닝과 호출 방식의 병렬 최적화를 통해 데이터베이스 부하를 획기적으로 줄였으며,
장기적으로 발생 가능했던 커넥션 오류 및 로딩 지연 이슈를 사전에 방지할 수 있게 되었습니다.
또한, 엔드유저 입장에서도 썸네일 배지 로딩 속도 향상이라는 체감 성능 개선 효과를 기대할 수 있습니다.
덧붙이며, 캐싱? 리팩토링? 다양한 접근도 가능 할 것입니다
이번 개선은 쿼리 구조와 호출 방식을 조정하는 방식으로 접근했지만,
사실 이와 유사한 문제는 다양한 방법으로 접근 가능합니다.
- Redis나 메모리 캐시 사용: 조회 결과를 TTL 기준으로 캐싱
- 로딩 시점 Lazy 처리: 진입 단계에서가 아닌 사용자 인터랙션 시 조회
- 비동기 배치 처리 + 클라이언트 Polling 구조 도입
개선은 하나의 방향만 있는 것이 아니며,
현재의 인프라/비즈니스 제약 조건 속에서 가장 실현 가능한 방식부터 적용하는 것이 중요하다고 생각합니다.
기술적 문제 해결이 단순히 수치를 줄이는 데 그치지 않고,
팀과 사용자 모두에게 의미 있는 개선으로 연결되도록 노력했던, 의미있는 경험이었습니다. 😎
댓글남기기