Particione os índices de pesquisa

O Spanner suporta índices de pesquisa não particionados e particionados. Esta página descreve como criar um índice de pesquisa particionado no Spanner.

É criado um índice não particionado quando a cláusula PARTITION BY é omitida na definição do índice. Num índice não particionado, uma consulta tem de ler a partir de todas as divisões do índice. Isto limita a potencial escalabilidade das consultas de pesquisa de texto completo.

Por outro lado, os índices particionados subdividem o índice em unidades mais pequenas, uma para cada partição exclusiva. As consultas só podem pesquisar numa única partição de cada vez, especificada por uma condição de igualdade na cláusula WHERE. As consultas em relação a índices particionados são geralmente mais eficientes do que as consultas em relação a índices não particionados, porque o Spanner só precisa de ler dados para uma única partição. A partição do índice de pesquisa é análoga ao prefixo da chave de um índice secundário.

Por exemplo, suponhamos que existem 1 000 000 de SingerIds numa base de dados e os dois índices seguintes:

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;

A seguinte consulta seleciona o índice AlbumsIndexBySingerId porque apenas pesquisa dados de um único cantor. Normalmente, este tipo de consulta 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')

Também é possível forçar uma consulta a usar AlbumsUnpartitionedIndex para devolver os mesmos resultados. No entanto, usa mais recursos, porque a consulta tem de aceder a todas as divisões do índice e filtrar todos os álbuns de todos os cantores para encontrar o token "feliz", em vez de apenas as divisões correspondentes ao cantor singer1.

No entanto, há alturas em que a aplicação precisa de pesquisar todos os álbuns em vez dos álbuns de um cantor específico. Nestes casos, tem de usar um índice não particionado:

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

A recomendação geral é usar a granularidade mais precisa da partição que seja prática e adequada para a consulta. Por exemplo, se a aplicação consultar uma caixa de correio eletrónico em que cada consulta está restrita a uma caixa de correio específica, particione o índice de pesquisa no ID da caixa de correio. No entanto, se a consulta precisar de pesquisar em todas as caixas de correio, um índice não particionado é mais adequado.

Determinadas aplicações podem exigir várias estratégias de partição para satisfazer os respetivos requisitos de pesquisa específicos. Por exemplo, um sistema de gestão de inventário pode ter de suportar consultas filtradas por tipo de produto ou fabricante. Além disso, algumas aplicações podem precisar de várias pré-ordenagens, como a ordenação por hora de criação ou modificação. Nestes cenários, é recomendado que crie vários índices de pesquisa, cada um otimizado para as consultas correspondentes. O otimizador de consultas do Spanner seleciona automaticamente um índice para cada consulta.

O que se segue?