OFFSET은 점프가 아니라 읽고 버리는 방식

원하는 10행만 보여도, DB는 그 앞의 정렬 결과를 먼저 확인해야 합니다.

깊은 페이지일수록 반환되는 데이터보다 폐기되는 데이터가 훨씬 많아지고, 그 사이 행이 바뀌면 페이지 경계도 함께 흔들립니다.

예시 요청
ORDER BY id DESC LIMIT 10 OFFSET 9990

DB 내부에서는 정렬된 결과를 앞에서부터 확인한 뒤, 마지막 10행만 반환합니다

실제 확인한 행 수 = OFFSET + LIMIT
9,991 ~ 10,000행 사용자에게 전달되는 이번 페이지
10,001행 이후 이번 요청에서는 보지 않음
실제 확인 10,000행
사용자 결과 10행

문제 1. 페이지가 깊어질수록 스캔 비용이 커집니다

1페이지
10행거의 읽자마자 반환
가벼움
1000페이지
10,000행대부분은 버리기 위한 읽기
느려짐
10000페이지
100,000행반환 10행보다 폐기 비용이 압도적
매우 비효율

문제 2. 조회 사이에 행이 바뀌면 페이지 경계가 흔들립니다

이미 본 페이지 1
100 .. 91
사용자 기대
다음 페이지 = 90 .. 81
중간에 새 글 101 INSERT
실제 OFFSET 10 결과
91 .. 82
새 행이 앞쪽에 끼어들면 91은 중복해서 다시 보이고, 원래 봐야 했던 81은 누락될 수 있습니다.