[SQL] LIMIT OFFSET 페이징 방식의 한계, 커서 페이징 대안

Hyunjun Kim·2025년 7월 18일
0

SQL

목록 보기
53/90

1. LIMIT OFFSET 페이징

대용량 데이터를 다룰 때, 웹 애플리케이션이나 API에서 페이징(paging)은 필수적인 기능이다.
MySQL에서는 대표적으로 LIMITOFFSET 키워드를 이용해 쉽게 페이징을 구현할 수 있지만, 이 방식은 데이터가 많아질수록 성능 저하가 발생할 수 있다.
이번 글에서는 MySQL의 LIMIT .. OFFSET .. 동작 원리와 한계, 그리고 이를 극복하는 커서 페이징(cursor pagination) 방식을 소개한다.


2. LIMIT OFFSET 기본 구조 및 사례

LIMIT OFFSET을 활용한 간단한 예제를 먼저 살펴보자.
다음은 LeetCode 176번 문제인 "두 번째로 높은 급여 조회"를 위한 SQL 쿼리이다.

SELECT (
  SELECT DISTINCT salary
  FROM Employee
  ORDER BY salary DESC
  LIMIT 1 OFFSET 1
) AS SecondHighestSalary;
  • ORDER BY salary DESC로 급여를 내림차순 정렬한다.
  • DISTINCT로 중복을 제거한다.
  • LIMIT 1 OFFSET 1을 통해 첫 번째(가장 높은) 급여를 건너뛰고, 두 번째로 높은 급여를 선택한다.
  • 만약 두 번째로 높은 급여가 없으면 결과는 NULL이 된다.

이와 같은 구조는 간단한 조회에는 유용하지만, 데이터가 많고 OFFSET 값이 커질수록 성능상 이슈가 발생할 수 있다.

이를 확인하기 위해 다음과 같은 페이징 쿼리를 살펴보자.

SELECT id 
FROM comment
WHERE is_deleted = FALSE
LIMIT 15 
OFFSET 10000;


3. LIMIT OFFSET 동작 원리

  • 위 쿼리는 is_deleted = FALSE 조건을 만족하는 데이터 중, 10001번째부터 15개를 조회하려는 쿼리이다.
  • 하지만 MySQL 내부에서는 0번째 행부터 10000번째 행까지 데이터를 모두 읽고 버린 후, 10001번째부터 15개만 반환한다.
  • 즉, OFFSET이 클수록 MySQL은 읽고 버리는 데이터 양이 많아져 쿼리 비용이 증가하게 된다.


4. LIMIT OFFSET 방식의 한계

  • 성능 저하: OFFSET이 커질수록 쿼리의 수행 시간이 선형적으로 증가한다.
  • 일관성 문제: 페이징 사이에 데이터가 삽입되거나 삭제되면, 중복 조회 또는 누락 현상이 발생할 수 있다.
  • 스케일 문제: 대량의 데이터를 가진 테이블에서 페이지 번호가 높을수록 사용성 저하가 발생한다.


5. No OFFSET 방식: 커서 페이징(Cursor Pagination)

OFFSET 방식의 문제를 해결하기 위해, 커서 기반 페이징(cursor pagination)을 사용하는 방법이 있다.
이 방식은 마지막에 조회한 레코드의 고유값(예: id)을 커서(cursor)로 활용하여, 다음 페이지를 조회하는 쿼리이다.

예시 쿼리는 다음과 같다.

SELECT id
FROM comment
WHERE is_deleted = FALSE AND id < :last_id
ORDER BY id DESC
LIMIT 15;
  • 인덱스를 활용하여 id < :last_id 조건을 만족하는 데이터 중 가장 최신의 15개만 조회한다.
  • OFFSET처럼 데이터를 스캔하고 버리지 않기 때문에, 성능상 이점이 크다.
  • 이 방식은 SNS의 무한 스크롤 구조와 유사하며, 실시간성과 성능 모두 확보할 수 있는 방식이다.


6. LIMIT OFFSET vs Cursor Pagination 비교

구분LIMIT OFFSETCursor Pagination
성능OFFSET이 커질수록 성능 저하인덱스를 활용하여 빠른 조회 가능
데이터 변경 대응중복 혹은 누락 발생 가능일관성 유지에 유리
구현 복잡도간단약간 복잡 (마지막 커서 값 관리 필요)
사용 사례소규모, 변경이 적은 데이터에 적합대용량 데이터, 실시간 데이터에 적합


7. 결론

  • MySQL의 LIMIT OFFSET 페이징은 간단하지만, 대용량 데이터 환경에서는 성능 저하와 일관성 문제가 발생할 수 있다.
  • 특히 OFFSET 값이 클 경우, 무의미한 데이터 스캔 비용이 쿼리 성능을 저하시킨다.
  • 이에 대한 대안으로 커서 기반 페이징을 도입하면, 인덱스를 활용한 효율적인 페이징이 가능하다.
  • MySQL 8.0 이상에서는 커버링 인덱스, 정렬된 PK 등을 활용하여 커서 페이징을 최적화할 수 있다.
  • 실제 서비스 환경에서는 두 페이징 방식의 장단점을 비교하여, 목적에 따라 적절한 방식으로 선택하는 것이 중요하다.

profile
Data Analytics Engineer 가 되

0개의 댓글