PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie stellt man einem API-Client 1.000.000 Datenbankergebnisse zur Verfügung?

Die Tabelle hat einen Primärschlüssel. Nutzen Sie es.

Statt LIMIT und OFFSET , führen Sie Ihre Paging mit einem Filter für den Primärschlüssel durch. Sie haben dies mit Ihrem Kommentar angedeutet:

Paging mit Zufallszahlen (Fügen Sie "GREATER THAN ORDER BY" zu jeder Abfrage hinzu)

aber es gibt nichts Zufälliges darüber, wie Sie es tun sollten.

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

Erlauben Sie dem Client, beide Parameter anzugeben, die letzte ID, die er gesehen hat, und die Anzahl der abzurufenden Datensätze. Ihre API muss entweder einen Platzhalter, einen zusätzlichen Parameter oder einen alternativen Aufruf für "fetch the first" enthalten n IDs", wobei WHERE weggelassen wird -Klausel aus der Abfrage, aber das ist trivial.

Dieser Ansatz verwendet einen ziemlich effizienten Index-Scan, um die Datensätze in Ordnung zu bringen, und vermeidet im Allgemeinen eine Sortierung oder die Notwendigkeit, alle übersprungenen Datensätze zu durchlaufen. Der Client kann entscheiden, wie viele Zeilen er gleichzeitig haben möchte.

Dieser Ansatz unterscheidet sich vom LIMIT und OFFSET Ansatz auf eine zentrale Art und Weise:gleichzeitige Modifikation. Wenn Sie INSERT in die Tabelle mit einer Taste tiefer als ein Schlüssel, den ein Kunde bereits gesehen hat, wird dieser Ansatz seine Ergebnisse überhaupt nicht ändern, während der OFFSET Annäherung wird eine Reihe wiederholen. Ebenso, wenn Sie DELETE eine Zeile mit einer niedrigeren als bereits gesehenen ID ändern sich die Ergebnisse dieses Ansatzes nicht, während OFFSET überspringt eine unsichtbare Zeile. Es gibt jedoch keinen Unterschied für nur anhängende Tabellen mit generierten Schlüsseln.

Wenn Sie im Voraus wissen, dass der Client die gesamte Ergebnismenge haben möchte, ist es am effizientesten, ihm einfach die gesamte Ergebnismenge ohne dieses Paging-Geschäft zu senden. Da würde ich würde Verwenden Sie einen Cursor. Lesen Sie die Zeilen aus der DB und senden Sie sie so schnell an den Client, wie der Client sie akzeptiert. Diese API müsste Grenzen setzen, wie langsam der Client sein darf, um eine übermäßige Backend-Last zu vermeiden; für einen langsamen Client würde ich wahrscheinlich auf Paging umschalten (wie oben beschrieben) oder das gesamte Cursor-Ergebnis in eine temporäre Datei spoolen und die DB-Verbindung schließen.

Wichtige Vorbehalte :

  • Erfordert einen UNIQUE Einschränkung / UNIQUE Index oder PRIMARY KEY zuverlässig sein
  • Unterschiedliches gleichzeitiges Änderungsverhalten zu Limit/Offset, siehe oben