Suchindexe partitionieren

Spanner unterstützt sowohl nicht partitionierte als auch partitionierte Suchindexe. Auf dieser Seite wird beschrieben, wie Sie einen partitionierten Suchindex in Spanner erstellen.

Ein nicht partitionierter Index wird erstellt, wenn die Klausel PARTITION BY in der Indexdefinition weggelassen wird. Bei einem nicht partitionierten Index muss eine Abfrage aus allen Indexaufteilungen gelesen werden. Das schränkt die potenzielle Skalierbarkeit von Volltextsuchanfragen ein.

Partitionierte Indexe unterteilen den Index dagegen in kleinere Einheiten, eine für jede eindeutige Partition. Abfragen können jeweils nur in einer einzelnen Partition gesucht werden, die durch eine Gleichheitsbedingung in der WHERE-Klausel angegeben wird. Abfragen auf partitionierte Indexe sind im Allgemeinen effizienter als Abfragen auf nicht partitionierte Indexe, da Spanner nur Daten für eine einzelne Partition lesen muss. Die Partitionierung des Suchindexes entspricht dem Schlüsselpräfix eines sekundären Index.

Angenommen, es gibt 1.000.000 SingerIds in einer Datenbank und die folgenden beiden Indexe:

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  SingerId STRING(MAX) NOT NULL,
  ReleaseTimestamp INT64 NOT NULL,
  AlbumTitle STRING(MAX),
  AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
  SingerId_Tokens TOKENLIST AS (TOKEN(SingerId)) HIDDEN
) PRIMARY KEY(SingerId, AlbumId);

CREATE SEARCH INDEX AlbumsUnpartitionedIndex
ON Albums(AlbumTitle_Tokens, SingerId_Tokens);

CREATE SEARCH INDEX AlbumsIndexBySingerId
ON Albums(AlbumTitle_Tokens)
PARTITION BY SingerId;

In der folgenden Abfrage wird der Index AlbumsIndexBySingerId ausgewählt, da nur nach Daten für einen einzelnen Sänger gesucht wird. Bei dieser Art von Abfrage werden in der Regel weniger Ressourcen verbraucht.

SELECT AlbumId
FROM Albums
WHERE SingerId = "singer1"
AND SEARCH(AlbumTitle_Tokens, 'happy')

Es ist auch möglich, AlbumsUnpartitionedIndex für eine Abfrage zu erzwingen, um dieselben Ergebnisse zurückzugeben. Sie beansprucht jedoch mehr Ressourcen, da die Abfrage auf alle Indexaufteilungen zugreifen und alle Alben für alle Sänger filtern muss, um das Token „glücklich“ zu finden, anstatt nur die Aufteilungen, die dem Sänger singer1 entsprechen.

Es gibt jedoch Fälle, in denen die Anwendung alle Alben durchsuchen muss, nicht nur die Alben eines bestimmten Sängers. In diesen Fällen müssen Sie einen nicht partitionierten Index verwenden:

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'piano concerto 1')

Im Allgemeinen wird empfohlen, die Partitionierung so fein wie möglich zu gestalten, was für die Abfrage praktisch und angemessen ist. Wenn die Anwendung beispielsweise ein E-Mail-Postfach abfragt, bei dem jede Abfrage auf ein bestimmtes Postfach beschränkt ist, partitionieren Sie den Suchindex nach der Postfach-ID. Wenn bei der Abfrage jedoch alle Postfächer durchsucht werden müssen, ist ein nicht partitionierter Index besser geeignet.

Bestimmte Anwendungen erfordern möglicherweise mehrere Partitionierungsstrategien, um ihren spezifischen Suchanforderungen gerecht zu werden. Ein Inventarverwaltungssystem muss beispielsweise Suchanfragen unterstützen, die nach Produkttyp oder Hersteller gefiltert werden. Außerdem sind für einige Anwendungen möglicherweise mehrere Vorsortierungen erforderlich, z. B. eine Sortierung nach Erstellungs- oder Änderungszeit. In diesen Fällen sollten Sie mehrere Suchindizes erstellen, die jeweils für die entsprechenden Suchanfragen optimiert sind. Der Abfrageoptimierer von Spanner wählt automatisch einen Index für jede Abfrage aus.

Nächste Schritte