인기 게시글 조회 성능 최적화

기존 코드의 소요 시간 측정

 

@Transactional(readOnly = true)
public PostListDTO getPostPreviewList(final int page) {

	Pageable pageable = getPageable(page);

	return PostListDTO.toPostListDTO(postRepository.findAllByOrderByViewsDesc(pageable));

}
@Query("SELECT p FROM Post p ORDER BY p.views DESC")
Page<Post> findAllByOrderByViewsDesc(Pageable pageable);

 

기존 코드를 통해서 인기 게시글 조회 소요 시간을 측정하게 되면 다음과 같은 결과가 나오게 된다.

 

동시에 발생한 요청이 실행된 횟수가 총 500회 일 경우, 요청 당 평균 응답 시간은 5.145 초가 소요되었다.

 

TPS(Transaction Per Second)를 의미하는 Throughput은 25.0 TPS로 측정되었다.

 

  • 측정 시간

Number Of Threads : 1

Number Of Threads : 100

Number Of Threads : 300

Number Of Threads : 500

 

성능 최적화 하기

 

캐시(Cache)

 

  • 데이터베이스의 부하를 줄이고, 빠른 데이터 액세스를 위해 자주 사용하는 데이터를 미리 저장.
  • Redis를 사용하여 쿼리 결과 캐싱하는 방식으로 진행을 함.
  • 비용이 크며, 자주 사용되는 API에 대해서 캐싱해두면 효율이 많이 좋아지나, 캐싱방법에 따라, 데이터가 업데이트되어도 여전히 오래된 데이터가 조회될 수 있음

 

// 게시글 목록 조회, 조회수 내림차순 정렬, Redis 캐시 적용
@Cacheable(value = "postList", key = "#page", cacheManager = "cacheManager")
@Transactional(readOnly = true)
public PostListDTO getPostPreviewListWithCache(final int page) {

	Pageable pageable = getPageable(page);

	return PostListDTO.toPostListDTO(postRepository.findAllByOrderByViewsDesc(pageable));

}

 

동시에 발생한 요청이 실행된 횟수가 총 500회 일 경우, 요청 당 평균 응답 시간은 0.718 초로 대폭 감소되었다. 사용자들이 자주 접하게 되는 인기 게시물의 쿼리 결과를 캐시 해놓음으로써 빠른 데이터 액세스가 일어남을 확인할 수 있다.

 

  • 측정 시간

Number Of Threads : 1

Number Of Threads : 100

Number Of Threads : 300

Number Of Threads : 500

 

인덱싱

 

@Table(indexes = {@Index(name = "idx_views", columnList = "views DESC")})
@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Post

인덱스 데이터베이스에서 데이터를 빠르게 검색하기 위한 자료 구조를 말한다.

 

하지만 과도한 인덱스 생성 시 쓰기 성능이 저하될 수 있다. 인덱스는 데이터가 많을수록 효율이 극대화된다.

 

 

JPA에서의 인덱스 생성 어노테이션을 사용해서 테이블을 만들게 되면 위와 같은 쿼리문이 발생한다. 해당 인덱스 생성을 통해서 Post 테이블의 조회수 칼럼을 기준으로 내림차순으로 정렬된 데이터를 빠르게 조회할 수 있다.

 

 

동시에 발생한 요청이 실행된 횟수가 총 500회 일 경우, 요청 당 평균 응답 시간은 0.546 초로 대폭 감소되었다.

 

  • 측정 시간

Number Of Threads : 1

Number Of Threads : 100

Number Of Threads : 300

Number Of Threads : 500