공부의 일상

[JPA Pageable] 페이지네이션 속도 비교, 향상

leeds123 2024. 5. 29. 13:37

Pageable, OFFSET LIMIT 속도 비교

요즘 단순히 구현보다는 그 이상의 성능 향상 등에 대해서 공부 중이고 실습 중이다. (백엔드 직무로 취업을 준비하려면 단순 구현에서 끝내면 안 된다 생각했기 때문...)

 

Daily Report 프로젝트에서 진행한 Spring Boot 기반의 API 서버를 건드려보기로 했다.
가장 먼저 눈에 띈 것은 페이지네이션 API (페이지네이션만 1주일 넘게 잡고 있다...)
이 API는 아래와 같이 프로젝트 첫 화면에서 게시글을 보여주기 위해 개발해둔 API였다.

 

먼저, API의 속도를 개선하기 위해 먼저 작성된 코드를 확인했다.

내가 작성해둔 코드는 JPA의 Pageable을 사용해서 페이지네이션 API를 생성했었다.

@GetMapping("/board/pagination")
public Page<Board> boardGetPagination(@PageableDefault(page = 0, size = 4, sort ="id", direction = Sort.Direction.DESC) Pageable pageable) {
	Page<Board> result = boardService.getBoardsPagination(pageable);
	return boardService.getBoardsPagination(pageable);
  }

이렇게 간단하게 구현만 해두고 끝을 냈던 나... (왜 그랬을까...)

 

페이지네이션 구현 방법에 대해 알아보니 크게 3가지가 있었다.
1. JPA - Pageable (기존 사용했던 방식)
2. OFFSET, LIMIT
3. CURSOR

 

 

이 3가지 중에서 CURSOR 방식은 빠르긴 하지만 무한 스크롤 구현에 적합하고 원하는 페이지로 한 번에 이동할 수 없다는 단점 때문에 프로젝트 성향과 맞지 않다고 판단하여 1번과 2번 속도를 비교했다.

 

먼저 기존 방식인 1번의 속도를 측정했다.

(속도 측정에는 Postman의 Runner를 사용했다.) + (파이썬 Script를 작성해 100만 건의 임시 데이터를 생성했다. -> 총 25만 개의 페이지)

 

JPA - Pageable

1-1. 100번 호출

평균 응답 속도는 749ms 임을 알 수 있다.

 

1-2. 1000번 호출

평균 응답 속도는 681ms 임을 알 수 있다.

 

 

@Query, OFFSET, LIMIT

두 번째로, 직접 @Query로 OFFSET과 LIMIT을 사용해 native query 문을 작성했다.

@Query(value = "SELECT * FROM board_data ORDER BY id DESC LIMIT :limit OFFSET :offset", nativeQuery = true)
    public List<Board> findBoardByPagination(@Param("limit") int limit, @Param("offset") int offset);

 

1번과 똑같이 100번 호출, 1000번 호출로 진행했다.

 

2-1. 100번 호출

437ms로 1번 보다 312ms 단축시켰다.

 

 

2-2 1000번 호출

 

512ms로 1번 보다 169ms 단축시켰다.

 

결론적으로 2번 방식 (@Query)이 더욱 빠른 응답 속도를 보이는 것을 확인했고, 현재 2번 방식으로 코드를 변경해두었다.

(하지만 2번 방식도 결코 빠른 속도는 아닌 것 같아 다른 방법을 찾아보려 한다.)