페이지네이션
페이지네이션은 웹 사이트에서 데이터를 한 페이지에 특정 수만큼 표시하도록 하는 기능입니다.
사용자가 다음 페이지를 클릭하면 다음 데이터 세트가 표시되는 것이죠
일반적으로 흔하게 대용량 데이터를 유저에게 제공할 때 쉽게 접할 수 있는 방식입니다.
오프셋 기반 페이지네이션
오프셋 기반 페이지네이션은 가장 일반적인 페이지네이션 방식으로, 데이터의 시작 위치(오프셋)와 한 페이지에 표시할 데이터의 수(리미트)를 지정합니다
예를 들어, 다음과 같이 SQL 쿼리에서 사용할 수 있습니다.
public Page<Post> getPosts(Long memberId, Pageable pageable) {
var posts = findAllBy(memberId, pageable);
var count = getCount(memberId);
return new PageImpl<>(posts, pageable, count);
}
page와 size를 받아서 게시물을 조회하는 구조입니다
이러한 구조 때문에, 오프셋 기반 페이지네이션에서는 데이터베이스 서버는 요청된 페이지의 데이터에 도달하기 위해 특정 수의 레코드를 건너뛰어야합니다.
이 건너 뒤는 프로세스를 스캔이라합니다.
왜 스캔이 필요할까?
1000페이지의 책을 상상해보면, 8000페이지부터 읽으란 요청을 받은 경우, 800페이지에 도달하기 위해 이전 799페이지를 넘겨야겠죠?
각 페이지를 개별적으로 읽진 않더라도 여전치 지나쳐야 합니다.
마찬가지로 데이터 베이스 서버가 오프셋에서 시작하는 레코드를 검색하도록 요청을 받은 경우
SELECT * FROM table LIMIT 20 OFFSET 800
검색을 시작하려면, 처음 800개의 레코드를 지나서 이동(스캔)해야 하는 것이죠
성능 이슈
따라서, 오프셋 페이지 네이션은 오프셋이 작을 때는 잘 작동하지만 오프셋이 증가함에 따라 쿼리 속도가 느려집니다.
오프셋이 증가할 때 쿼리 성능 저하
오프셋이 증가하게 되면, 해당 페이지를 조회하기 위해 데이터베이스는 시작부터 오프셋까지의 모든 데이터를 스캔해야 합니다.
예를 들어, 사용자가 100번째 페이지를 요청했다면, 데이터베이스는 처음부터 99번째 페이지까지의 모든 데이터를 스캔해야 합니다
이는 시간과 자원을 많이 소모하게 됩니다.
데이터베이스 부하 증가
이러한 방식은 단순한 쿼리에 대해서는 문제가 되지 않지만, 큰 데이터셋에 대해서는 상당한 부하를 발생시킬 수 있습니다.
데이터베이스가 불필요하게 많은 양의 데이터를 스캔해야 하기 때문에, 응답 시간이 느려지고 데이터베이스의 부하가 증가하게 됩니다.
커서 기반 페이지 네이션
앞서 말한 페이지네이션의 문제를 해결하기 위해, 커서 기반 페이지네이션을 사용할 수 있습니다.
커서는 데이터셋의 특정 위치를 가리키는 포인터로, "이 특정 항목 다음의 n개의 항목을 주세요"라는 방식으로 작동합니다
아래 예시를 함께 봐봅시다
public PageCursor<Post> getPosts(Long memberId, CursorRequest cursorRequest) {
var posts = findAllBy(memberId, cursorRequest);
long nextKey = getNextKey(posts);
return new PageCursor<>(cursorRequest.next(nextKey), posts);
}
클라이언트는 서버에 요청을 보내 첫 5개의 게시물을 요청합니다.
서버는 반환된 목록의 마지막 게시물을 가리키는 커서와 함게 처음 5개의 게시물을 반환합니다
클라이언트는 다른 요청을 보내 커서의 다음 5개의 게시물을 요청합니다
성능 이슈
커서 기반 페이지네이션은 대량의 데이터를 처리할 때 훨씬 효율적입니다.
커서 기반 페이지네이션은 항상 특정 커서 다음의 일정 수의 항목만을 요청하므로 대량의 데이터 스캔을 피할 수 있습니다
궁금증
운영 체제에도 페이지네이션이 있지 않는가
운영체제는 메모리 관리를 위해 페이지네이션과 비슷한 개념을 가지고 있지만, 이는 웹 페이지네이션과는 다르게 작동합니다.
운영체제의 페이지네이션은 프로세스가 물리 메모리에 저장될 때 고정된 크기의 블록(페이지)으로 데이터를 나누는 것을 의미합니다.
이는 웹 페이지네이션과 달리 사용자 인터페이스나 데이터 제공과는 직접적인 관련이 없습니다.
부족한 점이나 잘못 된 점을 알려주시면 시정하겠습니다 :>
'DEV > Backend' 카테고리의 다른 글
커서 기반 페이지네이션 (0) | 2023.06.09 |
---|---|
오프셋 기반 페이지네이션 (0) | 2023.06.09 |
조회 최적화를 위한 인덱스 (2) | 2023.06.02 |
DTO(Data Transfer Object) (0) | 2023.06.02 |
정규화 (0) | 2023.06.01 |