트러블슈팅

리뷰 개수 조회 성능 개선 및 동시성 문제 해결

sudaruuu 2026. 3. 19. 11:54

문제 상황

리뷰 기능을 구현하면서
식당별 총 리뷰 개수를 함께 조회해야 하는 요구사항이 있었다.

초기에는 리뷰 목록을 조회하면서
리뷰 개수를 함께 계산하는 방식으로 처리할 수 있었다.

하지만 이 방식은 다음과 같은 문제가 있었다.

  • 리뷰 목록 조회 시마다 리뷰 개수를 다시 계산해야 함
  • 리뷰 데이터가 많아질수록 처리 비용이 증가
  • 동일한 요청이 반복될 경우 불필요한 DB 접근 발생

또한 리뷰 작성이 동시에 발생하는 경우

  • 여러 요청이 같은 시점에 처리되면서
  • 리뷰 개수 값이 정확하게 증가하지 않을 가능성도 존재했다.

즉,
조회 성능 문제 + 동시성 문제가 동시에 존재하는 상황이었다.


원인 분석

문제의 핵심 원인은 두 가지였다.

1. 조회 시마다 계산하는 구조

리뷰 개수를 매번 계산하는 방식은

  • 요청이 들어올 때마다 추가 연산이 발생하고
  • 데이터가 많아질수록 비용이 계속 증가한다.

조회가 많아질수록 성능에 부담이 되는 구조였다.

2. 동시성 제어가 없는 증가 로직

리뷰 생성 시 단순히

totalReviewCount++;

 

와 같이 처리할 경우

  • 동시에 여러 요청이 들어오면
  • 일부 증가 값이 반영되지 않을 수 있다.

즉, 데이터 값의 정확성이 깨질 수 있는 구조였다.


해결 방법

다음과 같은 방식으로 구조를 개선하였다.

1. 집계 컬럼 도입

store 테이블에 totalReviewCount 컬럼을 추가하여
리뷰 개수를 별도로 저장하도록 변경하였다.

조회 시 계산 없이 바로 값을 사용할 수 있도록 개선

2. 리뷰 생성 시 값 직접 반영

Store store = storeRepository.findByIdWithPessimisticLock(storeId)
        .orElseThrow(...);

store.increaseReviewCount();
public void increaseReviewCount() {
    this.totalReviewCount++;
}

3. 비관적 락 적용

동시성 문제를 해결하기 위해

  • 식당 조회 시 비관적 락을 적용하여
  • 동시에 하나의 요청만 해당 데이터를 수정할 수 있도록 제한하였다.

이를 통해 리뷰 개수 값이 정확하게 반영되도록 보장하였다.


결과

구조 변경 이후 다음과 같은 개선 효과를 얻을 수 있었다.

  • 리뷰 개수를 조회할 때 추가 계산이 필요 없어짐
  • 불필요한 DB 접근 감소
  • 조회 성능 개선

또한

  • 동시성 문제를 방지하여
  • 리뷰 개수 값이 정확하게 유지되도록 개선하였다.

느낀 점

이번 작업을 통해

  • 단순 조회 로직도 데이터가 많아지면 성능 문제가 될 수 있다는 점
  • 동시에 데이터를 수정하는 경우 반드시 동시성 제어가 필요하다는 점

을 이해할 수 있었다.

특히

조회 성능 개선과 데이터 정확성을 함께 고려하는 설계가 중요하다는 것을 배웠다.