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'). LIMIT без ORDER BY не гарантирует порядок результатов.

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 использует TOP n (с вариантами TOP (n) PERCENT / WITH TIES) для первых N строк, а с 2012 — OFFSET ... FETCH для постраничного вывода. Для работы OFFSET/FETCH ORDER BY обязателен. Ключевого слова LIMIT в SQL Server нет.

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, но есть команды чтения диапазонов: ZRANGE/ZREVRANGE start stop (по индексу) или ZRANGEBYSCORE ... LIMIT offset count для Sorted Set; LRANGE для List. Эти команды дают доступ, похожий на постраничный вывод.

Elasticsearch

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

В Elasticsearch 'size' задаёт число возвращаемых hits, а 'from' — число пропускаемых (эквивалент LIMIT/OFFSET). from+size не может превышать index.max_result_window (по умолчанию 10,000); для глубокого постраничного вывода используйте 'search_after' (keyset) или PIT (point-in-time).

Открыть в DBAtlas →