본문 바로가기

개발 프로젝트/2024 제로베이스 프로젝트

제로베이스 연습프로젝트 : 매장 테이블 예약 서비스 (3) 최적화 고려

1. Store Rating 커스텀 쿼리

 

Store의 Rating 칼럼은 ReviewEntity 레코드들의 평균값에 의존하고 있는데, I/O Bound를 고려하여 서버로 전송되는 데이터를 줄이기 위해서 Review의 rating값을 평균값을 내는 작업을 쿼리를 통해서 DB서버 내에서 작동시킴


// Custom query to calculate the average rating for a specific store
@Query("SELECT ROUND(AVG(r.rating), 1) FROM ReviewEntity r WHERE " +
        "r.storeEntity = :storeEntity")
Double reupdateAverageRating (@Param("storeEntity") StoreEntity storeEntity);

 

2. N+1 Problem


    @PreAuthorize("#memberId == authentication.principal.memberId")
    public ReviewDto deleteReview(String memberId, String reviewId) {
        log.info("Setting review status to DELETED for reviewId: {}", reviewId);

        ReviewEntity reviewEntity = reviewRepository.findByReviewID(reviewId).orElseThrow(
                () -> new CustomException(ErrorCode.REVIEW_NOT_FOUND)
        );
// Todo : N+1문제이므로 Fetch with JPQL or QueryDSL 할것.
        if(!(Objects.equals(reviewEntity.getUserEntity().getUserId(), memberId)
                || Objects.equals(reviewEntity.getStoreEntity().getPartnerEntity().getPartnerId(), memberId))){
            throw new CustomException(ErrorCode.MEMBERID_REVIEWUSER_UNMATCHED);
        }

 

RevieEntity를 통해서 PartnerId를 조회하게되는데, 이를 위해서 N+1번 DB접근을 하게된다. 이경우 1. CustomQuery를 통해서 eagerfetching을 하거나 2. 캐슁을 통해서 메모리에 저장하는 최적화가 필요하다.