Suchergebnisse paginieren

Webanwendungen paginieren häufig die Daten, während sie den Nutzern angezeigt werden. Die Endanwendenden erhält eine Seite mit Ergebnissen, und wenn er zur nächsten Seite navigiert, abgerufen und präsentiert werden. Auf dieser Seite wird beschrieben, wie Sie Seitenumbrüche in den Suchergebnissen einfügen, wenn eine Volltextsuche in Spanner.

Übersicht

Es gibt zwei Möglichkeiten, paginated queries in Spanner zu implementieren: schlüsselbasierte Paginierung (empfohlen) und offsetbasierte Paginierung.

Die schlüsselbasierte Paginierung ist eine Methode zum Abrufen von Suchergebnissen in kleineren, überschaubareren Teilen, die gleichzeitig für konsistente Ergebnisse bei Anfragen sorgt. Eine eindeutige Kennung (der „Schlüssel“) aus dem letzten Ergebnis einer Seite wird als Referenzpunkt verwendet, um die nächsten Ergebnisse abzurufen.

Spanner empfiehlt im Allgemeinen, die schlüsselbasierte Paginierung zu verwenden. Die offsetbasierte Paginierung ist zwar einfacher zu implementieren, hat aber zwei erhebliche Nachteile:

  1. Höhere Abfragekosten: Bei der offsetbasierten Paginierung werden dieselben Ergebnisse wiederholt abgerufen und verworfen, was zu höheren Kosten und einer geringeren Leistung führt.
  2. Inkonsistente Ergebnisse: Bei paginierten Abfragen wird jede Seite in der Regel mit einem anderen Lesezeitstempel abgerufen. Die erste Seite kann beispielsweise aus einer Suchanfrage um 13:00 Uhr stammen und die nächste aus einer Suchanfrage um 13:10 Uhr. Das bedeutet, dass sich die Suchergebnisse zwischen den Suchanfragen ändern können, was zu inkonsistenten Ergebnissen auf den einzelnen Seiten führt.

Bei der schlüsselbasierten Paginierung wird dagegen eine eindeutige Kennung (Schlüssel) aus dem letzten Ergebnis einer Seite verwendet, um die nächsten Ergebnisse abzurufen. So wird sowohl ein effizienter Abruf als auch konsistente Ergebnisse gewährleistet, auch wenn sich die zugrunde liegenden Daten ändern.

Um für Stabilität bei den Seitenergebnissen zu sorgen, könnte die Anwendung alle Abfragen für verschiedene Seiten zum selben Zeitstempel senden. Dies kann jedoch fehlschlagen, wenn die Abfrage den Zeitraum für die Versionsspeicherung überschreitet (Standardeinstellung: 1 Stunde). Dieser Fehler tritt beispielsweise auf, wenn version_gc eine Stunde beträgt und der Endnutzer die ersten Ergebnisse um 13:00 Uhr abgerufen und um 15:00 Uhr auf Weiter geklickt hat.

Schlüsselbasierte Paginierung verwenden

Bei der schlüsselbasierten Paginierung wird das letzte Element der vorherigen Seite gespeichert und als Ausgangspunkt für die Abfrage der nächsten Seite verwendet. Dazu muss die Abfrage die in der ORDER BY-Klausel angegebenen Spalten zurückgeben und die Anzahl der Zeilen mit LIMIT begrenzen.

Damit die schlüsselbasierte Paginierung funktioniert, muss die Abfrage die Ergebnisse nach einer bestimmten Gesamtbestellung. Am einfachsten ist es, eine beliebige Gesamtbewertungsreihenfolge auszuwählen und dann bei Bedarf Spalten für den Fall von Gleichständen hinzuzufügen. In den meisten Fällen entspricht die Gesamtreihenfolge der Sortierung nach Suchindex. und die eindeutige Spaltenkombination ist der Primärschlüssel der Basistabelle.

Bei Verwendung unseres Albums-Beispielschemas sieht die Abfrage für die erste Seite so aus: Folgendes:

SELECT AlbumId, ReleaseTimestamp
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY ReleaseTimestamp DESC, AlbumId
LIMIT 10;

AlbumId ist der Tiebreaker, da ReleaseTimestamp kein Schlüssel ist. Es kann zwei verschiedene Alben mit demselben Wert für ReleaseTimestamp geben.

Zum Fortsetzen führt die Anwendung dieselbe Abfrage noch einmal mit der Klausel WHERE aus. ein, mit dem die Ergebnisse der vorherigen Seite eingeschränkt werden. Die zusätzliche Bedingung die Richtung (aufsteigend oder absteigend), wichtige Stichpunkte, und die Reihenfolge der NULL-Werte für Spalten, in denen Nullwerte zulässig sind.

In unserem Beispiel ist AlbumId die einzige Schlüsselspalte (in aufsteigender Reihenfolge) darf nicht NULL sein, daher lautet die Bedingung:

SELECT AlbumId, ReleaseTimestamp
FROM Albums
WHERE (ReleaseTimestamp < @last_page_release_timestamp
       OR (ReleaseTimestamp = @last_page_release_timestamp
           AND AlbumId > @last_page_album_id))
      AND SEARCH(AlbumTitle_Tokens, @p)
ORDER BY ReleaseTimestamp DESC, AlbumId ASC
LIMIT @page_size;

Spanner interpretiert diese Art von Bedingung als suchbar. Das bedeutet, dass Spanner den Index nicht für Dokumente liest, die Sie herausfiltern. Diese Optimierung macht die schlüsselbasierte Paginierung viel effizienter als die offsetbasierte Paginierung.

Offsetbasierte Paginierung verwenden

Bei der offsetbasierten Paginierung werden die LIMIT- und OFFSET-Klauseln der SQL-Abfrage verwendet, um Seiten zu simulieren. Der Wert für LIMIT gibt die Anzahl der Ergebnisse pro Seite an. Der Wert von OFFSET wird für die erste Seite auf null und für die zweite Seite die Seitengröße festgelegt. und die dritte Seite verdoppeln.

Die folgende Abfrage ruft beispielsweise die dritte Seite mit einer Seitengröße von 50 ab:

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY ReleaseTimestamp DESC, AlbumId
LIMIT 50 OFFSET 100;

Verwendungshinweise:

  • Die ORDER BY-Klausel wird dringend empfohlen, um eine einheitliche Sortierung zu gewährleisten zwischen den Seiten.
  • Verwenden Sie in Produktionsabfragen Abfrageparameter anstelle von Konstanten, um anzugeben, LIMIT und OFFSET, um das Abfrage-Caching effizienter zu gestalten. Weitere Informationen finden Sie unter Abfrageparameter.

Nächste Schritte