DBAtlas · Atlas d'exploitation des bases de données

Limitation de lignes / pagination (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;

Sert à limiter/paginer un jeu de résultats. Depuis Oracle 12c, la syntaxe standard OFFSET n ROWS FETCH NEXT m ROWS ONLY est prise en charge. Auparavant, on utilisait la pseudo-colonne ROWNUM ; ROWNUM étant attribué avant le tri, il est obligatoire d'encapsuler une sous-requête avec 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 prend en charge à la fois LIMIT n OFFSET m et la forme standard OFFSET ... FETCH. Les grandes valeurs d'OFFSET sont lentes ; pour la pagination profonde, la pagination par clé (keyset / 'WHERE id > last_id') est plus efficace. LIMIT sans ORDER BY ne garantit pas l'ordre des résultats.

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 utilisent le mot-clé LIMIT sous deux formes : LIMIT row_count OFFSET offset ou LIMIT offset, row_count. MySQL 8.0.19+ accepte aussi la syntaxe standard FETCH. La pagination keyset est recommandée pour les performances avec un OFFSET profond.

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 utilise TOP n (avec les variantes TOP (n) PERCENT / WITH TIES) pour les N premières lignes et, depuis 2012, OFFSET ... FETCH pour la pagination. ORDER BY est obligatoire pour qu'OFFSET/FETCH fonctionne. SQL Server n'a pas de mot-clé LIMIT.

MongoDB

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

Dans MongoDB, limit() fixe le nombre de documents renvoyés et skip() le nombre de documents ignorés ; combinés à sort(), ils assurent la pagination. Les grandes valeurs de skip sont coûteuses ; pour la pagination profonde, une requête par plage (keyset) basée sur la dernière valeur vue est préférable.

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 n'a pas de LIMIT SQL, mais il dispose de commandes de lecture par plage : ZRANGE/ZREVRANGE start stop (par index) ou ZRANGEBYSCORE ... LIMIT offset count pour les Sorted Sets ; LRANGE pour les Lists. Ces commandes offrent un accès de type pagination.

Elasticsearch

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

Dans Elasticsearch, 'size' fixe le nombre de hits renvoyés et 'from' le nombre ignoré (l'équivalent de LIMIT/OFFSET). from+size ne peut pas dépasser index.max_result_window (10 000 par défaut) ; pour la pagination profonde, utilisez 'search_after' (keyset) ou un PIT (point-in-time).

Ouvrir dans DBAtlas →