Spanner supporta gli indici di ricerca non partizionati e partizionati search indexes. Questa pagina descrive come creare un indice di ricerca partizionato in Spanner.
Un indice non partizionato viene creato quando la clausola PARTITION BY viene omessa nella definizione dell'indice. In un indice non partizionato, una query deve leggere da tutte le suddivisioni dell'indice. Ciò limita la potenziale scalabilità delle query di ricerca a testo intero.
Gli indici partizionati, d'altra parte, suddividono l'indice in unità più piccole, una per ogni partizione univoca. Le query possono cercare solo all'interno di una singola partizione alla volta, specificata da una condizione di uguaglianza nella clausola WHERE. Le query sugli indici partizionati sono in genere più efficienti delle query sugli indici non partizionati perché Spanner deve leggere solo i dati di una singola partizione. Il partizionamento dell'indice di ricerca è analogo al prefisso della chiave di un indice secondario.
Supponiamo, ad esempio, che in un database siano presenti 1.000.000 di SingerIds e i due indici seguenti:
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;
La query seguente seleziona l'indice AlbumsIndexBySingerId perché cerca solo i dati di un singolo cantante. Questo tipo di query in genere utilizza meno risorse.
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')
È anche possibile forzare
una query a utilizzare AlbumsUnpartitionedIndex per restituire gli stessi risultati.
Tuttavia, utilizza più risorse, perché la query deve accedere a tutte le suddivisioni dell'indice e filtrare tutti gli album di tutti i cantanti per trovare il token "happy", anziché solo le suddivisioni corrispondenti al cantante singer1.
Tuttavia, a volte l'applicazione deve cercare in tutti gli album anziché negli album di un cantante specifico. In questi casi, devi utilizzare un indice non partizionato:
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')
La raccomandazione generale è di utilizzare la granularità di partizionamento più precisa che sia pratica e appropriata per la query. Ad esempio, se l'applicazione esegue query su una casella di posta elettronica in cui ogni query è limitata a una casella di posta elettronica specifica, partiziona l'indice di ricerca in base all'ID della casella di posta elettronica. Tuttavia, se la query deve cercare in tutte le caselle di posta elettronica, un indice non partizionato è più adatto.
Alcune applicazioni potrebbero richiedere più strategie di partizionamento per soddisfare i propri requisiti di ricerca specifici. Ad esempio, un sistema di gestione dell'inventario potrebbe dover supportare query filtrate per tipo di prodotto o produttore. Inoltre, alcune applicazioni potrebbero richiedere più preordinamenti, ad esempio l'ordinamento in base all'ora di creazione o modifica. In questi scenari, ti consigliamo di creare più indici di ricerca, ognuno ottimizzato per le query corrispondenti. L'ottimizzatore di query di Spanner seleziona automaticamente un indice per ogni query.
Passaggi successivi
- Scopri di più sulla tokenizzazione e sui tokenizer di Spanner.
- Scopri di più sugli indici di ricerca.
- Scopri di più sugli indici numerici.