Ich mache API über HTTP, die große Zeilen von PostgreSQL mit Seitenumbruch abruft. In normalen Fällen implementiere ich Paginierungen normalerweise über naive OFFET
/ LIMIT
-Klausel. Es gibt jedoch einige spezielle Anforderungen in diesem Fall:
Wie kann ich die Mission erreichen? Ich bin bereit, mein ganzes Datenbankschema dafür zu ändern!
Wenn man annimmt, dass nur die Reihenfolge der Ergebnisse schwankt und nicht die Daten in den Zeilen, ist Fredriks Antwort sinnvoll. Ich würde jedoch die folgenden Ergänzungen vorschlagen:
Speichern Sie die ID-Liste in einer postgresql-Tabelle mit dem Array -Typ und nicht im Speicher. Wenn Sie im Speicher arbeiten, sollten Sie sich auf DOS-Speicherverbrauchsangriffe einstellen, es sei denn, Sie verwenden etwas wie Redis mit automatischem Ablauf und Speicherbegrenzungen. Ich stelle mir vor, dass es ungefähr so aussehen würde:
%Vor%Sie müssen entscheiden, ob cursor_token und result_ids von Benutzern gemeinsam genutzt werden können, um die Speicheranforderungen und die Zeit zu verringern, die für die Ausführung der ersten Abfrage pro Benutzer erforderlich ist. Wenn sie freigegeben werden können, wählen Sie ein Cache-Fenster, sagen Sie 1 oder 5 Minute (n), und erstellen Sie dann nach einer neuen Anfrage das Cache_Token für diesen Zeitraum und prüfen Sie, ob die Ergebnis-IDs bereits für dieses Token berechnet wurden. Wenn nicht, füge eine neue Zeile für dieses Token hinzu. Sie sollten wahrscheinlich eine Sperre um den Prüf- / Einfügecode hinzufügen, um gleichzeitige Anforderungen für ein neues Token zu bearbeiten.
Haben Sie einen geplanten Hintergrundjob, der alte Token / Ergebnisse bereinigt und sicherstellt, dass Ihr Client-Code alle Fehler im Zusammenhang mit abgelaufenen / ungültigen Tokens verarbeiten kann.
Denken Sie nicht einmal daran, echte db-Cursor dafür zu verwenden.
Das Speichern der Ergebnis-IDs in Redis-Listen ist eine andere Möglichkeit, dies zu umgehen (siehe LRANGE -Befehl), aber seien Sie vorsichtig beim Ablauf und Speicherverbrauch, wenn Sie diesen Pfad gehen. Ihre Redis-Taste wäre das cursor_token und die IDs wären die Mitglieder der Liste.
Ich weiß absolut nichts über PostgreSQL, aber ich bin ein ziemlich anständiger SQL Server-Entwickler, also würde ich gerne einen Blick darauf werfen:)
Wie viele Zeilen / Seiten erwarten Sie, dass ein Benutzer maximal pro Sitzung durchsucht werden kann? Wenn Sie zum Beispiel erwarten, dass ein Benutzer für jede Sitzung maximal 10 Seiten durchsucht (jede Seite enthält 50 Zeilen), können Sie diesen Maximalwert verwenden und den Webservice so einrichten, dass der Cache zwischengespeichert wird, wenn der Benutzer die erste Seite anfordert 10 * 50 Zeilen (oder nur die Id: s für die Zeilen, hängt davon ab, wie viel Speicher / gleichzeitige Benutzer Sie bekommen haben).
Dies würde sicherlich dazu beitragen, Ihren Webservice in mehr als einer Hinsicht zu beschleunigen. Und es ist ziemlich einfach zu implementieren. Also:
Sie könnten auch die Zahlen erhöhen, ein Array von 500 int: s würde nur 2K Speicher belegen, aber es hängt auch davon ab, wie schnell Sie Ihre anfängliche Abfrage / Antwort wollen.
Ich habe eine ähnliche Technik auf einer Live-Website verwendet, und als der Benutzer auf Seite 10 weiterging, wechselte ich einfach zu Abfragen. Ich denke, eine andere Lösung wäre, das Array weiter zu erweitern / zu füllen. (Die Abfrage erneut ausführen, aber die bereits eingeschlossene ID ausschließen: s).
Wie auch immer, hoffe das hilft!
Tags und Links postgresql http pagination cursor continuous