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 PARTITION BY-Klausel in der Indexdefinition weggelassen wird. Bei einem nicht partitionierten Index muss eine Abfrage alle Indexaufteilungen lesen. Dadurch wird die potenzielle Skalierbarkeit von Volltextsuchanfragen eingeschränkt.
Bei partitionierten Indexen wird der Index in kleinere Einheiten unterteilt, 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 für partitionierte Indexe sind in der Regel effizienter als Abfragen für nicht partitionierte Indexe, da Spanner nur Daten für eine einzelne Partition lesen muss. Das Partitionieren des Suchindex entspricht dem Schlüsselpräfix eines sekundären Index.
Angenommen, es gibt 1.000.000 SingerIds in einer Datenbank und die folgenden zwei Indexe:
GoogleSQL
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;
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
singerid character varying NOT NULL,
releasetimestamp bigint NOT NULL,
albumtitle character varying,
albumtitle_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
singerid_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.token(singerid)) VIRTUAL 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;
Mit der folgenden Abfrage wird der Index AlbumsIndexBySingerId ausgewählt, da nur Daten für einen einzelnen Sänger gesucht werden. Für diese Art von Abfrage sind in der Regel weniger Ressourcen erforderlich.
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SingerId = "singer1"
AND SEARCH(AlbumTitle_Tokens, 'happy')
PostgreSQL
SELECT albumid
FROM albums
WHERE singerid = 'singer1'
AND spanner.search(albumtitle_tokens, 'happy')
Es ist auch möglich, eine Abfrage zu erzwingen, AlbumsUnpartitionedIndex zu verwenden, um dieselben Ergebnisse zurückzugeben.
Dafür werden jedoch mehr Ressourcen benötigt, da für die Abfrage auf alle Indexaufteilungen zugegriffen und alle Alben für alle Sänger gefiltert werden muss, um das Token „happy“ zu finden. Das ist aufwendiger, als nur die Aufteilungen für Sänger singer1 zu durchsuchen.
Es gibt jedoch Fälle, in denen die Anwendung alle Alben durchsuchen muss und nicht nur die Alben eines bestimmten Sängers. In diesen Fällen müssen Sie einen nicht partitionierten Index verwenden:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'piano concerto 1')
PostgreSQL
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'piano concerto 1')
Im Allgemeinen wird empfohlen, die feinste Granularität der Partitionierung zu verwenden, die für die Abfrage praktisch und angemessen ist. Wenn die Anwendung beispielsweise ein E-Mail-Postfach abfragt, wobei jede Abfrage auf ein bestimmtes Postfach beschränkt ist, partitionieren Sie den Suchindex anhand der Postfach-ID. Wenn die Abfrage jedoch alle Postfächer durchsuchen muss, ist ein nicht partitionierter Index besser geeignet.
Für bestimmte Anwendungen sind möglicherweise mehrere Partitionierungsstrategien erforderlich, um ihren spezifischen Suchanforderungen gerecht zu werden. Beispielsweise muss ein Bestandsverwaltungssystem möglicherweise Anfragen unterstützen, die nach Produkttyp oder Hersteller gefiltert werden. Außerdem benötigen einige Anwendungen möglicherweise mehrere Vorsortierungen, z. B. nach Erstellungs- oder Änderungszeit. In diesen Fällen empfiehlt es sich, mehrere Suchindexe zu erstellen, die jeweils für die entsprechenden Anfragen optimiert sind. Die Abfrageoptimierung von Spanner wählt automatisch einen Index für jede Abfrage aus.
Nächste Schritte
- Informationen zur Tokenisierung und zu Spanner-Tokenizern
- Weitere Informationen zu Suchindexen
- Weitere Informationen zu numerischen Indexen