Particionar í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 leerse de todas las divisiones del índice. Esto limita la escalabilidad potencial de las consultas de búsqueda de texto completo.

Por otro lado, los índices particionados subdividen el índice en unidades más pequeñas, una por cada partición única. Las consultas solo pueden buscar en una partición a la vez, especificada por una condición de igualdad en la cláusula WHERE. Las consultas en índices particionados suelen ser más eficientes que las consultas en índices sin particiones, ya que Spanner solo necesita leer datos de una 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 dos índices siguientes:

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 cantante. Este tipo de consulta suele usar 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 puedes forzar una consulta para que use AlbumsUnpartitionedIndex y devuelva los mismos resultados. Sin embargo, utiliza más recursos, ya que la consulta necesita 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 en los de un cantante concreto. 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 más fina de partición que sea práctica y adecuada para la consulta. Por ejemplo, si la aplicación consulta un buzón de correo en el que cada consulta se limita a un buzón específico, particiona el índice de búsqueda en el ID del buzón. Sin embargo, si la consulta necesita buscar en todos los buzones, es mejor usar un índice sin particiones.

Es posible que algunas aplicaciones requieran varias estrategias de partición para adaptarse a sus requisitos de búsqueda específicos. Por ejemplo, un sistema de gestión de inventario puede necesitar admitir consultas filtradas por tipo de producto o fabricante. Además, algunas aplicaciones pueden necesitar varias ordenaciones previas, como ordenar por hora de creación o de modificación. En estos casos, se recomienda crear varios índices de búsqueda, cada uno optimizado para las consultas correspondientes. El optimizador de consultas de Spanner selecciona automáticamente un índice para cada consulta.

Siguientes pasos