문제 상황
인기 차트 생성 로직을 구현한 이후,
차트가 정상적으로 생성되고 조회까지 되는지 확인하는 과정에서 구조적인 아쉬움을 느꼈다.
PR 과정에서 CodeRabbit 리뷰를 통해 Top100 제한이 비효율적인 방식으로 처리되고 있다는 점을 확인하게 되었다.
코드 리뷰 피드백
CodeRabbit는 다음과 같은 문제를 지적했다.
- Top100 제한을 DB에서 처리하지 않고
- 서비스 로직(애플리케이션 레벨)에서 후처리로 적용하고 있는 구조

원인 분석
기존 구현에서는 다음과 같이 Top100 제한을 적용하고 있었다.
List<TrackPlayCountProjection> results =
playbackRepository.countWeeklyValidPlayByTrack(
startDateTime,
snapshotDateTime,
MINIMUM_VALID_PLAY_SECONDS
);
List<TrackPlayCountProjection> top100 = results.stream()
.limit(TOP_CHART_LIMIT)
.toList();
이 구조에서는
- DB는 전체 데이터를 반환하고
- 애플리케이션이 결과를 잘라내는 방식이었다
즉, 조회 범위 제어를 DB가 아닌 서비스 코드가 담당하고 있었다.
문제점
- 불필요한 데이터 조회 발생
- DB → 애플리케이션 전송 비용 증가
- 메모리 사용 증가
- 데이터 규모 증가 시 성능 저하
데이터가 많아질수록 비효율이 커지는 구조였다.
해결 과정
Top N 제한은 DB 쿼리 단계에서 처리하도록 구조를 변경했다.
List<TrackPlayCountProjection> results =
playbackRepository.countWeeklyValidPlayByTrack(
startDateTime,
snapshotDateTime,
MINIMUM_VALID_PLAY_SECONDS,
TOP_CHART_LIMIT
);
@Query("""
SELECT p.trackId AS trackId, COUNT(p) AS playCount
FROM Playback p
WHERE p.startedAt >= :startDateTime
AND p.startedAt < :endDateTime
AND p.playedDuration >= :minimumSeconds
GROUP BY p.trackId
ORDER BY COUNT(p) DESC
LIMIT :limit
""")
List<TrackPlayCountProjection> countWeeklyValidPlayByTrack(
LocalDateTime startDateTime,
LocalDateTime endDateTime,
int minimumSeconds,
int limit
);
쿼리 단계에서 결과를 제한하도록 변경했다.
적용 결과
- Top100 제한을 DB에서 처리 → 성능 개선
- 불필요한 데이터 조회 제거
- 데이터 전송량 감소
- 메모리 사용 감소
정리
Top N 제한은 애플리케이션이 아닌 DB에서 처리해야 한다.
조회 범위 제어를 DB에서 수행함으로써 성능과 효율성을 동시에 개선할 수 있었다.
느낀 점
이번 개선을 통해 단순히 기능을 구현하는 것을 넘어서
- 조회 성능을 고려한 쿼리 설계의 중요성
- 처리 책임을 어디에 둘 것인지에 대한 설계 기준
을 고민하는 것이 필요하다는 것을 느꼈다.
결과적으로 동작하는 코드보다, 효율적으로 동작하는 구조를 만드는 것이 중요하다는 점을 체감할 수 있었다.
'Fivefy 프로젝트 > 트러블슈팅' 카테고리의 다른 글
| PlaylistTrack reorder 동시성 테스트 검증 기준 개선 (0) | 2026.05.11 |
|---|---|
| AWS EC2 + RDS 환경에서 Spring Boot 배포 (0) | 2026.05.08 |
| 인기 차트 생성 로직 리팩토링과 조회 흐름 정리 (0) | 2026.04.28 |
| PlaylistTrack 순서 변경 최적화 전체 재정렬을 부분 재정렬로 개선 (0) | 2026.04.23 |
| Soft Delete 구조에서 DB 유니크 제약을 통한 데이터 무결성 보완 (0) | 2026.04.22 |