기존에 사용했던 DRF의 PageNumberPagination
는 Offset 방식의 페이지네이션이다.
Offset 방식이란 SQL로 표현하면 아래와 같다.
SELECT id FROM models ORDER BY id ASC LIMIT 10 OFFSET 0 # 1페이지
SELECT id FROM models ORDER BY id ASC LIMIT 10 OFFSET 10 # 2페이지
SELECT id FROM models ORDER BY id ASC LIMIT 10 OFFSET 20 # 3페이지
해당 방식의 장점은 다음과 같다.
문제는 속도에서 나온다.
물론 쿼리의 규모가 작으면 문제가 없지만 쿼리의 규모가 크면 해당 방식은 비효율적이다.
아래의 쿼리를 보자
SELECT id FROM models ORDER BY id ASC LIMIT 500000,20 # 1페이지
500,000번째부터 20개를 가져오는 쿼리인데 해당 쿼리를 가져오기 위해서는
50만 쿼리를 가져오고 -> 그 뒤로 20개를 반환 -> 50만 쿼리를 삭제 하는 과정을 거친다.
즉, 20개를 가져오기위해 50만개의 쿼리를 불러오고 바로 삭제는 비효율적인 과정이다.
이러한 이유로 나온 것이 커서 기반 페이지네이션(Cursor-based Pagination)
이다.
주로 오픈 API에서 볼 수 있는 방식인데, 특정한 지점에 커서를 저장해두고 그 이후부터 불러오는 방식을 말한다.
예를 들면 20개가 1페이지를 이루는 API에서 80번 이후의 페이지를 가져오고 싶다.
SELECT id FROM models WHERE id>80 ORDER BY id ASC LIMIT 20
WHERE
을 활용하여 특정 지점(커서)를 불러오고 그 이후로 쿼리를 반환하는 방식이다.
그렇기 때문에 해당 방식을 사용하기 위해서는 반드시 유니크한 값이 필요하다.
DRF에서는 CursorPagination
클래스가 커서 기반 페이지네이션을 지원한다.