PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment fournir à un client API 1 000 000 de résultats de base de données ?

La table a une clé primaire. Profitez-en.

Au lieu de LIMIT et OFFSET , faites votre pagination avec un filtre sur la clé primaire. Vous y avez fait allusion avec votre commentaire :

Pagination utilisant des nombres aléatoires (Ajouter "GREATER THAN ORDER BY" à chaque requête)

mais il n'y a rien d'aléatoire dans la façon dont vous devriez le faire.

SELECT * FROM big_table WHERE id > $1 ORDER BY id ASC LIMIT $2

Autoriser le client à spécifier les deux paramètres, le dernier ID qu'il a vu et le nombre d'enregistrements à récupérer. Votre API devra avoir un espace réservé, un paramètre supplémentaire ou un autre appel pour "récupérer le premier n IDs" où il omet le WHERE clause de la requête, mais c'est trivial.

Cette approche utilisera une analyse d'index assez efficace pour mettre les enregistrements dans l'ordre, évitant généralement un tri ou la nécessité de parcourir tous les enregistrements ignorés. Le client peut décider du nombre de lignes qu'il veut à la fois.

Cette approche diffère de la LIMIT et OFFSET approche d'une manière clé :la modification simultanée. Si vous INSERT dans le tableau avec une touche inférieur qu'une clé que certains clients ont déjà vue, cette approche ne changera en rien ses résultats, alors que le OFFSET approche répétera une ligne. De même, si vous DELETE une ligne avec un ID inférieur à celui déjà vu, les résultats de cette approche ne changeront pas, alors que OFFSET sautera une rangée invisible. Il n'y a cependant aucune différence pour les tables en ajout uniquement avec des clés générées.

Si vous savez à l'avance que le client voudra l'ensemble des résultats, la chose la plus efficace à faire est simplement de lui envoyer l'ensemble des résultats sans aucune de ces activités de pagination. C'est là que je voudrais utiliser un curseur. Lisez les lignes de la base de données et envoyez-les au client aussi vite que le client les acceptera. Cette API devrait définir des limites sur la lenteur autorisée du client pour éviter une charge excessive du backend ; pour un client lent, je passerais probablement à la pagination (comme décrit ci-dessus) ou spoulerais tout le résultat du curseur dans un fichier temporaire et fermerais la connexion à la base de données.

Mises en garde importantes :

  • Nécessite un UNIQUE contrainte / UNIQUE index ou PRIMARY KEY être fiable
  • Comportement de modification simultanée différent pour limiter/décaler, voir ci-dessus