OFFSET은 점프가 아니라 읽고 버리는 방식
원하는 10행만 보여도, DB는 그 앞의 정렬 결과를 먼저 확인해야 합니다.
깊은 페이지일수록 반환되는 데이터보다 폐기되는 데이터가 훨씬 많아지고, 그 사이 행이 바뀌면 페이지 경계도 함께 흔들립니다.
예시 요청
ORDER BY id DESC LIMIT 10 OFFSET 9990
DB 내부에서는 정렬된 결과를 앞에서부터 확인한 뒤, 마지막 10행만 반환합니다
실제 확인한 행 수 = OFFSET + LIMIT
1 ~ 9,990행
읽었지만 결과에서 버림
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은 누락
될 수 있습니다.