[TIL] Product 도메인 성능 개선 작업 정리

김재진·2026년 5월 12일

내일배움캠프

목록 보기
70/70

1️⃣ Redis 캐시를 통한 반복 조회 성능 개선

🚨 문제

상품 목록·상세 API는 트래픽이 높아 동일 요청이 반복되는데, 매번 DB를 조회하면 부하가 빠르게 누적됩니다.
반대로 TTL을 길게 잡으면 변경사항 반영이 늦어 오래된 데이터(stale data) 노출 위험이 커집니다.

✅ 개선 내용

CacheConfig에 캐시 영역을 분리하고, 조회/변경 경로에 @Cacheable / @CacheEvict를 적용했습니다.

🗂️ 캐시 정책

캐시 키TTL적용 대상설계 의도
product:list30초목록 조회드랍 상태 전이 주기(30초)와 동기화
product:detail60초상세 조회목록 대비 변경 빈도가 낮아 TTL 확대

⚙️ 적용 포인트

  • ⚡ 동일 요청(status, sort, page, size)은 캐시 hit 시 DB를 우회
  • 🗑️ 상품·이미지·드랍 변경 시 @CacheEvict로 관련 캐시 즉시 제거
  • 🔒 재고는 실시간 정합성 중요도가 높아 캐시 대상에서 제외

📈 효과

  • 반복 조회 요청에서 DB read 부하 감소
  • 목록/상세 응답 속도 개선
  • TTL에만 의존하지 않고 변경 시 즉시 무효화하여 최신성 확보

🧠 기술적 의사결정

장기 TTL 대신 짧은 TTL + 명시적 무효화를 채택해,
"성능"과 "최신성" 사이 트레이드오프를 운영 가능한 수준으로 균형화했습니다.


2️⃣ @EntityGraph를 통한 N+1 쿼리 개선

🚨 문제

상품 상세 조회 시 연관 이미지(ProductImage)가 지연 로딩으로 개별 조회되어 N+1 쿼리 위험이 있었습니다.

✅ 개선 내용

ProductRepository 상세 조회 메서드에 @EntityGraph(attributePaths = "images")를 적용했습니다.

@EntityGraph(attributePaths = "images")
@Query("select p from Product p where p.id = :id")
Optional<Product> findDetailById(@Param("id") Long id);

📈 효과

  • 상세 조회 시 상품 + 이미지 데이터를 단일 조회 경로로 가져와 쿼리 수 감소
  • 응답 지연 시간의 분산(쿼리 다건 왕복) 완화

🧠 기술적 의사결정

상세 화면에 반드시 필요한 연관 데이터는 조회 시점에 명시적으로 함께 로드해
지연 로딩의 편의성보다 예측 가능한 성능을 우선했습니다.


3️⃣ Querydsl 기반 커스텀 정렬 + 페이징 최적화

🚨 문제

기본 JPA 정렬만으로는 "드랍 임박순" 처럼 서브쿼리가 필요한 복합 정렬을 표현하기 어렵고,
페이지 조회마다 count 쿼리를 과도하게 실행할 수 있습니다.

✅ 개선 내용

ProductRepositoryCustomImpl에서 Querydsl 커스텀 조회를 적용했습니다.

⚙️ 정렬 타입

정렬 타입기준
LATEST📅 등록일 내림차순
PRICE_HIGH💰 판매가 내림차순
PRICE_LOW💸 판매가 오름차순
DROP_IMMINENT⏳ 다음 드랍 시작시간 오름차순 + NULL 후순위

🔑 핵심 구현

  • JPAExpressions로 다음 드랍 시작시간 서브쿼리 계산
  • CASE WHEN 기반 null rank 처리
  • PageableExecutionUtils.getPage()로 count 쿼리 최적화

📈 효과

  • 복합 정렬 요구사항 충족
  • 불필요한 count 실행 감소로 페이징 성능 개선

🧠 기술적 의사결정

단순 구현 편의보다 "비즈니스 정렬 정확도 + 성능" 을 위해
Querydsl 커스텀 조회를 표준 목록 경로로 채택했습니다.


📊 개선 요약

항목적용 기술주요 효과
🔍 목록·상세 조회Redis 캐시 (@Cacheable + @CacheEvict)반복 요청 DB 부하 감소 + 최신성 확보
🖼️ 상세 이미지 로딩@EntityGraphN+1 쿼리 제거
🔀 목록 정렬·페이징Querydsl 서브쿼리 + PageableExecutionUtils복합 정렬 구현 및 count 쿼리 최적화
profile
개발공부 처음해보는 사람

0개의 댓글