Partitionner les index de recherche

Spanner est compatible avec les tables index de recherche. Cette page explique comment créer un index de recherche partitionné dans Spanner.

Présentation

Un index non partitionné est créé lorsque la clause PARTITION BY est omise dans la définition de l'index. Dans un index non partitionné, une requête doit lire toutes les divisions d'index. Cela limite la scalabilité potentielle des requêtes de recherche en texte intégral.

En revanche, les index partitionnés subdivisent l'index en unités plus petites, une pour chaque partition unique. Les requêtes ne peuvent effectuer de recherche que dans une seule partition à la fois, spécifiée par une condition d'égalité dans la clause WHERE. Les requêtes sur les index partitionnés sont généralement plus efficaces que les requêtes sur les index non partitionnés, car Spanner n'a besoin de lire que les données d'une seule partition. Le partitionnement de l'index de recherche est similaire au préfixe de clé d'une adresse de l'index.

Par exemple, supposons qu'une base de données contienne 1 000 000 SingerIds et que les deux index suivants:

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;

La requête suivante sélectionne l'index AlbumsIndexBySingerId, car elle ne recherche que les données d'un seul chanteur. Ce type de requête utilise généralement moins de ressources.

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

Vous pouvez également forcer une requête à utiliser AlbumsUnpartitionedIndex pour renvoyer les mêmes résultats. Toutefois, il utilise davantage de ressources, car la requête doit accéder à toutes les ressources d'index divise et filtre tous les albums afin que tous les chanteurs trouvent le jeton "happy" et pas seulement les partitions correspondant à l'artiste singer1.

Toutefois, il arrive que l'application doive rechercher dans tous les albums plutôt que dans ceux d'un chanteur spécifique. Dans ces cas, vous devez utiliser un indice non partitionné :

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

En règle générale, nous vous recommandons d'utiliser la granularité de partitionnement la plus fine qui soit pratique et adaptée à la requête. Par exemple, si l'application interroge une boîte de réception de messagerie où chaque requête est limitée à une boîte de réception spécifique, partitionnez l'index de recherche en fonction de l'ID de la boîte de réception. Toutefois, si la requête doit effectuer une recherche dans toutes les boîtes aux lettres, un index non partitionné est mieux adapté.

Certaines applications peuvent nécessiter plusieurs stratégies de partitionnement pour répondre à leurs besoins spécifiques en termes de recherche. Par exemple, un système de gestion des stocks peut être compatible avec les requêtes filtrées par type de produit ou par fabricant. De plus, certaines applications peuvent nécessiter plusieurs prétriages, tels que le tri par date de création ou de modification. Dans ces scénarios, nous vous recommandons de créer plusieurs index de recherche, chacun optimisé pour les requêtes correspondantes.

Étape suivante