DBAtlas · 데이터베이스 운영 아틀라스

행 제한 / 페이징(LIMIT/OFFSET, FETCH, ROWNUM, TOP)

Oracle

-- 12c+ standard: OFFSET/FETCH
SELECT name, salary FROM employee
ORDER BY salary DESC
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

-- Older versions: with ROWNUM
SELECT * FROM (
  SELECT name, salary FROM employee ORDER BY salary DESC
) WHERE ROWNUM <= 10;

결과 집합을 제한하거나 페이징하는 데 사용한다. Oracle 12c부터 표준 OFFSET n ROWS FETCH NEXT m ROWS ONLY를 지원한다. 그 이전에는 ROWNUM 의사 컬럼을 사용했으며, ROWNUM은 정렬 전에 할당되므로 ORDER BY 서브쿼리로 감싸는 것이 필수다.

PostgreSQL

-- LIMIT/OFFSET
SELECT name, salary FROM employee
ORDER BY salary DESC
LIMIT 10 OFFSET 20;

-- Standard equivalent: FETCH
SELECT name, salary FROM employee
ORDER BY salary DESC
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

PostgreSQL은 LIMIT n OFFSET m과 표준 OFFSET ... FETCH 형식을 모두 지원한다. 큰 OFFSET 값은 느리므로, 깊은 페이징에는 키 기반(keyset / 'WHERE id > last_id') 페이지네이션이 더 효율적이다. ORDER BY 없는 LIMIT은 결과 순서를 보장하지 않는다.

MySQL

-- LIMIT [offset,] row_count
SELECT name, salary FROM employee
ORDER BY salary DESC
LIMIT 10 OFFSET 20;

-- Short form: LIMIT offset, row_count
SELECT name, salary FROM employee ORDER BY salary DESC LIMIT 20, 10;

MySQL/MariaDB는 LIMIT 키워드를 두 가지 형식으로 사용한다: LIMIT row_count OFFSET offset 또는 LIMIT offset, row_count. MySQL 8.0.19+는 표준 FETCH 구문도 허용한다. 깊은 OFFSET 성능 문제에는 keyset 페이지네이션이 권장된다.

SQL Server

-- First N with TOP
SELECT TOP 10 name, salary FROM employee ORDER BY salary DESC;

-- OFFSET/FETCH for paging (2012+), ORDER BY mandatory
SELECT name, salary FROM employee
ORDER BY salary DESC
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

SQL Server는 첫 N개 행에 TOP n(TOP (n) PERCENT / WITH TIES 변형 포함)을, 2012부터 페이징에 OFFSET ... FETCH를 사용한다. OFFSET/FETCH가 동작하려면 ORDER BY가 필수다. SQL Server에는 LIMIT 키워드가 없다.

MongoDB

// Paging with skip/limit
db.employee.find()
  .sort({ salary: -1 })
  .skip(20)
  .limit(10)

MongoDB에서 limit()은 반환할 문서 수를, skip()은 건너뛸 문서 수를 지정하며, sort()와 함께 사용해 페이징을 제공한다. 큰 skip 값은 비용이 크므로, 깊은 페이징에는 마지막으로 본 값을 기준으로 한 범위(keyset) 쿼리가 권장된다.

Redis

# Range read on a sorted set (ZSET):
ZREVRANGE salary_sorted 20 29    # members ranked 21-30
# Range on a list:
LRANGE queue 0 9              # first 10 elements

Redis에는 SQL LIMIT이 없지만 범위 읽기 명령이 있다: Sorted Set에는 ZRANGE/ZREVRANGE start stop(인덱스 기반) 또는 ZRANGEBYSCORE ... LIMIT offset count, List에는 LRANGE. 이 명령들이 페이징과 유사한 접근을 제공한다.

Elasticsearch

GET employee/_search
{
  "from": 20,
  "size": 10,
  "sort": [ { "salary": "desc" } ]
}

Elasticsearch에서 'size'는 반환할 hit 수를, 'from'은 건너뛸 수를 지정한다(LIMIT/OFFSET에 해당). from+size는 최대 index.max_result_window(기본값 10,000)까지 가능하며, 깊은 페이징에는 'search_after'(keyset)나 PIT(point-in-time)를 사용한다.

DBAtlas에서 열기 →