본문 바로가기
성능 개선

Cursor기반 페이지네이션으로 응답 속도 개선하기

by sangyunpark99 2024. 10. 10.
OffSet기반 페이지네이션에서
속도 개선 경험을 작성한
글 입니다.

 

테스트 환경 : M1 mac - RAM 8GB

 

문제점

OffSet기반 페이지네이션을 사용할 때, DB에서 넘겨준 offset 위치를 찾기 위해서 맨 처음부터 데이터를 한번 훑게 됩니다.

만약, 총 100만개의 데이터가 DB에 존재하고, offset을 100만이라고 주는 경우, 100만개의 데이터를 훑은 다음에 이후의 데이터를 가져와야 하므로, 성능 저하가 발생할 수 있다. 즉, offset이 클수록 성능이 저하된다.

 

성능저하 확인하기

테스트 환경 : POSTMAN

DB에는 100만개의 더미데이터를 저장해 두었고, 극단적인 성능 저하를 확인하기 위해서, [offset:0, size:1][offset:999999, size:1]인 두 상황의 응답 속도를 비교해보도록 하겠습니다.

 

참고로 post 테이블에는 더 빠른 조회를 위해 인덱스를 생성해둔 상태입니다.

생성한 인덱스 (1) user_id, (2) created_date, (3) (user_id, created_date) - 복합 인덱스

 

 

오프셋이 0이고, 사이즈가 1인 경우

 

응답속도는 295ms가 걸립니다.

 

 

오프셋이 999999이고, 사이즈가 1인 경우

 

100만번째 데이터를 조회하는데 걸리는 응답속도는 558ms가 걸립니다.

 

같은 데이터를 조회하는 api임에도 응답속도가 약 2배정도 차이나게 됩니다.

 

 

 

해결 방법

 

Cursor기반 페이지네이션

100만번째 데이터를 조회하는데 걸리는 응답속도는 25ms가 걸립니다.

 

OffSet 기반 조회 api 보다 22배정도 더 빠릅니다.

 

빠른 이유

현재 저의 쿼리 코드는 커서 기반 페이지네이션 id를 기준으로 데이터를 조회하고 있습니다.

mysql에서 id는 primary key이므로, 테이블 생성시 자동으로 기본키 인덱스가 생성이 됩니다.

 

커서 기반 페이지네이션은 인덱스를 사용하여 특정 위치를 빠르게 찾고, 그 이후의 데이터를 읽기 때문에 성능이 뛰어납니다.오프셋 페이지네이션은 많은 양의 데이터를 스캔해야 하므로, 데이터가 많을수록 성능 저하가 발생합니다.

 

 

id가 아닌 다른 컬럼으로 커서 페이지네이션 조회

id가 아닌 다른 컬럼의 값으로 커서 페이지네이션 조회를 하려면, 그 컬럼에 대한 DB 인덱싱을 해주어야 합니다.

 

 

결론

게시판과 같이 Offset구조가 더 좋은 상황을 제외하고는, Cursor기반 페이지네이션을 사용하는 것도 고려해봐야 합니다.