데이터베이스 용어 사전
쿼리 최적화OFFSET · 페이지네이션 · 키셋 페이지네이션 · 커서 페이지네이션 · 키셋

OFFSET 페이지네이션

뒤 페이지일수록 느려지는 이유는 하나다 — 건너뛸 행을 실제로 읽고 버리기 때문이다.

목록을 나눠 보여 주는 두 가지 방식이 있고, 뒤로 갈수록 성능이 갈린다.

-- ❌ OFFSET 방식 — 페이지가 뒤로 갈수록 느려진다
SELECT * FROM orders ORDER BY id LIMIT 20 OFFSET 1000000;

-- ✅ 키셋(커서) 방식 — 페이지 번호와 무관하게 일정하다
SELECT * FROM orders WHERE id < :last_id ORDER BY id DESC LIMIT 20;

왜 OFFSET 이 느린가

OFFSET 1000000"100만 행을 건너뛰라" 가 아니라 "100만 행을 읽고 버리라" 는 뜻이다. DB 는 몇 번째 행인지 미리 알 수 없으므로 세면서 가야 한다.

1페이지    20행 읽음                      빠르다
1000페이지 20,000행 읽고 20행만 반환      느리다
50000페이지 1,000,000행 읽고 20행 반환    타임아웃

인덱스가 있어도 마찬가지다. 인덱스를 타더라도 건너뛸 항목을 하나씩 세어야 하기 때문이다. "인덱스만 잘 걸면 해결된다" 가 통하지 않는 드문 경우다.

키셋은 왜 일정한가

WHERE id < :last_id 는 인덱스에서 시작 지점으로 바로 진입한다. B-트리를 타고 내려가 그 자리를 찾은 뒤 20건만 읽는다. 1페이지든 5만 페이지든 하는 일이 같다.

정렬 키가 유일하지 않으면 깨진다

여기가 실제로 자주 틀리는 지점이다.

-- ❌ created_at 이 같은 행이 여럿이면 — 건너뛰거나 중복해서 나온다
SELECT * FROM orders WHERE created_at < :last_at ORDER BY created_at DESC LIMIT 20;

-- ✅ 유일한 키를 tie-breaker 로 덧붙인다
SELECT * FROM orders
WHERE (created_at, id) < (:last_at, :last_id)
ORDER BY created_at DESC, id DESC LIMIT 20;

같은 created_at 을 가진 행이 페이지 경계에 걸치면, 다음 페이지에서 그중 일부가 빠지거나 다시 나온다. 정렬 키에 유일한 값을 마지막에 붙여 전체 순서를 하나로 확정해야 한다.

MySQL·PostgreSQL 모두 위처럼 튜플 비교를 지원하고, 이 형태가 복합 인덱스를 그대로 탄다.

OFFSET 의 또 다른 문제 — 목록이 흔들린다

1페이지를 본 사이 새 주문 5건이 들어왔다
→ 2페이지에서 1페이지 마지막 항목들이 다시 보인다
반대로 앞쪽 행이 지워지면 → 건너뛰는 행이 생긴다

OFFSET 은 "몇 번째부터" 이므로 앞쪽이 바뀌면 기준이 통째로 흔들린다. 키셋은 "이 값 이후" 라서 앞쪽 변화에 영향받지 않는다. 성능뿐 아니라 정확성 문제이기도 하다.

그럼 언제 OFFSET 을 쓰나

키셋도 만능은 아니다.

  • 임의 페이지로 점프할 수 없다 — "37페이지로 가기" 가 불가능하다. 다음·이전만 된다
  • 전체 건수를 알기 어렵다COUNT(*) 를 따로 쳐야 하고 그것도 비싸다

그래서 판단이 갈린다.

상황선택
무한 스크롤·앱 목록키셋 — 점프가 필요 없다
관리자 화면의 페이지 번호OFFSET (단, 뒤 페이지 접근을 제한)
배치·전체 순회키셋 — 가장 확실하다
앞 몇 페이지만 보는 검색 결과OFFSET 으로도 충분하다

실무에서 흔한 절충은 OFFSET 상한을 두는 것이다. 1만 건 넘게 뒤로 가려 하면 검색 조건을 좁히라고 안내한다. 실제로 5만 페이지를 넘겨 보는 사용자는 없고, 대개 크롤러이거나 잘못된 호출이다.

면접 함정

  • "OFFSET 은 인덱스가 있으면 빠르다" → 인덱스가 있어도 건너뛸 행을 세어야 한다.
  • "키셋으로 바꾸면 항상 낫다" → 페이지 점프와 전체 건수를 포기하는 것이다.
  • "정렬 키 하나면 충분하다" → 값이 중복되면 페이지 경계에서 누락·중복이 생긴다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 실무 사고 사례 — 증상에서 원인까지