Particiona los índices de búsqueda

Spanner admite índices de búsqueda particionados y sin particionar. En esta página, se describe cómo crear un índice de búsqueda particionado en Spanner.

Se crea un índice sin particiones cuando se omite la cláusula PARTITION BY en la definición del índice. En un índice sin particiones, una consulta debe leer todas las divisiones del índice. Esto limita la escalabilidad potencial de las búsquedas en el texto completo.

Por otro lado, los índices particionados subdividen el índice en unidades más pequeñas, una para cada partición única. Las consultas solo pueden buscar dentro de una sola partición a la vez, especificada por una condición de igualdad en la cláusula WHERE. En general, las consultas en índices particionados son más eficientes que las consultas en índices no particionados, ya que Spanner solo necesita leer datos de una sola partición. La partición del índice de búsqueda es análoga al prefijo de clave de un índice secundario.

Por ejemplo, supongamos que hay 1,000,000 de SingerIds en una base de datos y los siguientes dos índices:

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 siguiente consulta selecciona el índice AlbumsIndexBySingerId porque solo busca datos de un solo cantante. Por lo general, este tipo de consultas usa menos recursos.

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')

También es posible forzar una búsqueda para que use AlbumsUnpartitionedIndex y devuelva los mismos resultados. Sin embargo, usa más recursos, ya que la búsqueda debe acceder a todas las divisiones del índice y filtrar todos los álbumes de todos los cantantes para encontrar el token "feliz", en lugar de solo las divisiones correspondientes al cantante singer1.

Sin embargo, hay ocasiones en las que la aplicación necesita buscar en todos los álbumes en lugar de los álbumes de un cantante específico. En estos casos, debes usar un índice sin particiones:

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 recomendación general es usar la granularidad de partición más fina que sea práctica y adecuada para la búsqueda. Por ejemplo, si la aplicación consulta un buzón de correo electrónico en el que cada consulta se restringe a un buzón específico, particiona el índice de búsqueda según el ID del buzón. Sin embargo, si la búsqueda debe realizarse en todos los buzones, un índice sin particiones es una mejor opción.

Es posible que algunas aplicaciones requieran varias estrategias de partición para satisfacer sus requisitos de búsqueda específicos. Por ejemplo, un sistema de administración de inventario podría necesitar admitir consultas filtradas por tipo de producto o fabricante. Además, es posible que algunas aplicaciones necesiten varias clasificaciones previas, como la clasificación por hora de creación o modificación. En estos casos, se recomienda que crees varios índices de búsqueda, cada uno optimizado para las búsquedas correspondientes. El optimizador de consultas de Spanner selecciona automáticamente un índice para cada consulta.

¿Qué sigue?