🔹페이지네이션(Pagination)
페이지네이션은 데이터를 일정한 단위로 나누어 제공하는 방식이다. 대량의 데이터를 한번에 조회하는 부담을 줄이고, 원하는 범위의 데이터를 효율적으로 조회할 수 있다.
🔸오프셋 기반 페이지네이션
LIMIT과 OFFSET을 사용해 특정 범위의 데이터를 조회하는 방식
장점
- 구현이 간단하고 직관적이다.
- 정적인 데이터 목록 조회에 적합하다.
단점
1. 데이터 중복 문제
사용자가 페이지를 요청하는 동안 새로운 데이터가 추가되거나 삭제되면, 중복된 데이터를 보게 될 수 있다.
예를 들어, 다음과 같은 쿼리를 실행한다고 가정한다.
SELECT * FROM patient_videos
ORDER BY created_at DESC
LIMIT 10
OFFSET 0;
1페이지의 결과로 ID 100번 ~ 91번까지 조회된다.
이후 사용자가 2페이지 데이터를 요청하기 전에 새로운 데이터들(101,102,103번)이 추가되었다.
이때, 사용자가 2페이지 데이터를 요청한다.
SELECT * FROM patient_videos
ORDER BY created_at DESC
LIMIT 10
OFFSET 10;
2페이지의 결과, ID 103~94까지 뛰어넘고 그 뒤 ID 93~84이 조회된다.
이 결과 ID 93,92,91 데이터가 중복 표시되어 사용자는 같은 데이터를 중복해서 보게 된다.
2. 성능 저하 문제
OFFSET 값이 커질수록 쿼리 성능이 저하된다.
select *
from patient_videos
order by create_at desc
limit 10
offset 1000000;
위 쿼리는 100만 개의 데이터를 읽고, 마지막 10개만 반환한다. 데이터가 많아질수록 불필요한 조회 비용이 증가하여 성능이 저하된다.
=> 따라서, 데이터가 많고 자주 변경되는 환경에서는 비효율적이다.
🔸커서 기반 페이지네이션 (Cursor-based Pagination)
OFFSET을 사용하지 않고, 마지막 항목의 고유 식별자 값(Cursor)을 기반으로 다음 데이터를 조회하는 방식
장점
- 새로운 데이터가 추가/삭제되어도 페이징이 깨지지 않는다.
- 어떤 페이지를 조회하든 항상 원하는 데이터 개수 만큼만 조회하여 성능상 이점이 존재한다.
SELECT * FROM patient_videos
WHERE created_at < '2024-02-17 10:01:00'
ORDER BY created_at DESC LIMIT 10;
해당 쿼리에서는 created_at을 cursor로 사용하여 OFFSET 없이 바로 필요한 데이터만 조회 가능하다.
LIMIT을 통해 일정 개수만 조회하며, 다음 페이지를 가져올 때는 마지막 데이터의 created_at 값을 기준으로 이어서 조회한다.
단점
- 이전 페이지로 돌아가기 어렵고, 특정 위치로 이동 불가능하다.
🔹Slice vs page
둘다 데이터 집합을 처리하기 위한 인터페이스이다.
Slice는 Streamable을 상속받는 인터페이스이고, page는 Slice를 상속한다.
Slice는 전체 페이지 개수나 데이터 개수를 제공하지 않고, 이전/다음 Slice가 존재하는지 정도 확인할 수 있다.
→ 무한 스크롤 등을 구현하는 경우 유용하다. Page에 비해 쿼리가 하나 덜 날라가므로 데이터가 많을 경우 성능상 유리하다.
Page는 전체 데이터 개수를 조회하는 쿼리를 한번 더 실행한다. 전체 데이터 개수나 페이지 개수가 필요한 경우 유용하다.
'Spring' 카테고리의 다른 글
[Spring] @Async와 프록시 객체 (0) | 2025.03.12 |
---|---|
멀티 Thread 테스트 : ExecutorService / CountDownLatch (1) | 2025.03.11 |
[SpringBoot] OpenAI API 적용하기 (0) | 2024.08.07 |
[Spring Security] 카카오 소셜 로그인 적용하기 (0) | 2024.07.08 |
[Spring Security] 회원가입, 로그인 테스트 (0) | 2024.07.03 |