본문 바로가기
트러블 슈팅

[MySQL] Pagination 방법론

by Shark_상어 2024. 3. 3.
728x90

업무 중 수 많은 데이터들을 쉽게 보기 위해서 페이지 네이션을 진행 했어야 했다.
페이지 네이션을 위해서 Limit, Offset를 찾아 본 결과, 성능적으로 문제가 많이 있다는 걸 검색을 통해서 알 수 있었다.

조사한 결과를 글로 적어 보고자 한다.


1. 성능 문제

OFFSET을 사용하면 데이터베이스는 지정된 숫자만큼의 레코드를 건너뛴 후 결과를 반환한다. 이는 데이터베이스가 모든 레코드를 실제로 읽은 후에 원하는 오프셋까지 건너뛰는 것을 의미한다. 이는 큰 데이터셋에서는 매우 비효율적일 수 있다. 특히 오프셋이 매우 크거나 데이터셋이 커지면 성능 문제가 발생할 수 있다.
아래의 이미지를 보게 되면 단번에 알 수 있다.

2. 일관성 문제

데이터베이스에서 OFFSET을 사용하여 페이징을 할 때, 새로운 데이터가 추가되거나 삭제될 경우 문제가 발생할 수 있다. 예를 들어, 페이지 1을 요청한 후 몇 초 후 다시 같은 요청을 보내면, 중간에 데이터가 추가되었다면 동일한 오프셋을 갖는 레코드를 얻을 수 없다.

3. 대규모 데이터셋에서의 문제

대규모 데이터셋에서 OFFSET을 사용하면 메모리 부하가 크게 증가할 수 있다. 예를 들어, 첫 페이지의 1000번째 항목을 보기 위해 1000개의 레코드를 모두 읽어야 한다. 위의 사진의 원리를 다시 적어 놓았다. 이는 메모리 사용량이 많고 성능 저하를 야기할 수 있다.

4. 인덱스의 한계

OFFSET을 사용하면 인덱스가 효율적으로 사용되지 않을 수 있다. 특히 데이터베이스가 정렬된 결과를 제공하는 경우, 오프셋이 커질수록 인덱스를 사용한 효율적인 검색이 어려워진다.

대안

위의 문제점을 해결하기 위해 대안적인 방법을 사용할 수 있다.

1. 커서 기반 페이징(cursor-based pagination) 방식이다.
이 방법은 이전 페이지의 마지막 항목을 기억하고 다음 페이지 요청 시에 그 항목 이후의 항목들을 가져오는 방식이다.
이를 통해 일관성이 유지되고 성능도 향상된다.

2. 지속적인 페이징(Persistent Pagination)이 있다.
이 방법은 페이지에 대한 메타데이터를 저장하여 다음 페이지 요청 시 이를 사용하여 데이터를 검색한다.
이는 더 효율적이지만 추가적인 저장 공간이 필요할 수 있다는 단점이 존재한다.

3. 범위 기반 페이징(Range-based pagination)은 데이터의 특정 범위를 기준으로 페이지를 나누는 방식이다.
예를 들어, ID 값이나 날짜를 기준으로 페이지를 나눌 수 있다.

이러한 대안적인 방법은 OFFSET을 사용할 때 발생할 수 있는 많은 문제를 해결할 수 있다.

위의 설명한 대안들은 다시 포스팅 할 예정이다.
물론 대안들도 단점이 존재하고, 현재 구현 하고자 프로젝트에 알맞게 선택하여 구현 하도록 하는 것을 추천한다.


728x90