Partitionner les index de recherche

Spanner est compatible avec les index de recherche non partitionnés et partitionnés. Cette page explique comment créer un indice de recherche partitionné dans Spanner.

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 à partir de toutes les divisions de l'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 analogue au préfixe de clé d'un index secondaire.

Par exemple, supposons qu'une base de données comporte 1 000 000 SingerIds et 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, elle utilise plus de ressources, car la requête doit accéder à toutes les divisions d'index et filtrer tous les albums de tous les chanteurs pour trouver le jeton "happy", plutôt que les divisions correspondant uniquement au chanteur 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 rechercher dans toutes les boîtes aux lettres, un indice non partitionné est plus adapté.

Certaines applications peuvent nécessiter plusieurs stratégies de partitionnement pour répondre à leurs exigences de recherche spécifiques. Par exemple, un système de gestion des stocks peut devoir prendre en charge 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