Acelerar expressões de correspondência de padrões

Os índices de pesquisa do Spanner podem acelerar expressões de correspondência de padrões, como LIKE, STARTS_WITH, ENDS_WITH e o predicado de correspondência de expressões regulares REGEXP_CONTAINS. Nesta página, descrevemos como criar e configurar um índice de pesquisa usando TOKENIZE_NGRAMS para acelerar predicados de correspondência de padrões.

Configurar um n-grama TOKENLIST para aceleração de correspondência de padrões

Para ativar a aceleração de expressões de correspondência de padrões, tokenizar uma coluna STRING em letras minúsculas com TOKENIZE_NGRAMS e armazenar a coluna STRING usando a cláusula STORING no GoogleSQL ou INCLUDE no PostgreSQL.

GoogleSQL

CREATE TABLE Albums (
AlbumId INT64 NOT NULL,
AlbumTitle STRING(MAX),
AlbumTitle_Ngram_Tokens TOKENLIST AS (
  TOKENIZE_NGRAMS(LOWER(AlbumTitle), ngram_size_min=>3, ngram_size_max=>4)) HIDDEN,
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsIndex
ON Albums(AlbumTitle_Ngram_Tokens) STORING (AlbumTitle);

PostgreSQL

CREATE TABLE albums (
albumid bigint NOT NULL,
album_title varchar,
album_title_ngrams_tokens spanner.tokenlist GENERATED ALWAYS AS (
  spanner.tokenize_ngrams(
    lower(album_title),
    ngram_size_min => 3,
    ngram_size_max => 4
  )
) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));

CREATE SEARCH INDEX albumsidx ON
albums(album_title_ngrams_tokens) INCLUDE (album_title);

Aceleração automática de consultas com predicados de correspondência de padrões

O otimizador de consultas pode acelerar as seguintes consultas usando AlbumsIndex com AlbumTitle_Ngram_Tokens. Se quiser, a consulta pode fornecer @{force_index = AlbumsIndex} para forçar o otimizador a usar AlbumsIndex.

GoogleSQL

No GoogleSQL, aceleramos LIKE, STARTS_WITH, ENDS_WITH e REGEXP_CONTAINS.

  • Predicado LIKE:

    SELECT AlbumId
    FROM Albums @{FORCE_INDEX=AlbumsIndex}
    WHERE AlbumTitle LIKE "%999%";
    
  • Predicado STARTS_WITH:

    SELECT AlbumId
    FROM Albums @{FORCE_INDEX=AlbumsIndex}
    WHERE STARTS_WITH(AlbumTitle, "apple")
    
  • Predicado ENDS_WITH:

    SELECT AlbumId
    FROM Albums @{FORCE_INDEX=AlbumsIndex}
    WHERE ENDS_WITH(AlbumTitle, "apple")
    
  • Predicado REGEXP_CONTAINS:

    SELECT AlbumId
    FROM Albums @{FORCE_INDEX=AlbumsIndex}
    WHERE REGEXP_CONTAINS(AlbumTitle, r"(good|great)[ ]+morning")
    

PostgreSQL

No PostgreSQL, aceleramos LIKE e STARTS_WITH.

  • Predicado LIKE:

    SELECT albumid
    FROM albums /*@ FORCE_INDEX = albumsidx */
    WHERE album_title like '%999%';
    
  • Predicado STARTS_WITH:

    SELECT albumid
    FROM albums /*@ FORCE_INDEX = albumsidx */
    WHERE starts_with(album_title, 'apple')
    

Pré-requisitos para aceleração

Para que o Spanner ative essa aceleração, as seguintes regras precisam ser atendidas:

  • O índice precisa armazenar a coluna STRING usando a cláusula STORING no GoogleSQL ou INCLUDE no PostgreSQL. Isso evita junções de volta caras à tabela base durante a pós-filtragem, o que é fundamental para o desempenho quando a pesquisa recupera documentos em excesso.
  • A coluna STRING precisa ser tokenizada usando TOKENIZE_NGRAMS.
  • A tokenização precisa ser aplicada a LOWER(column_name) em vez de column_name.
  • O padrão LIKE, o prefixo STARTS_WITH, o sufixo ENDS_WITH ou a expressão regular REGEXP_CONTAINS precisa ser especificado como um literal constante. Os parâmetros de consulta não são compatíveis para evitar aceleração em padrões muito curtos.
  • O padrão LIKE, o prefixo STARTS_WITH, o sufixo ENDS_WITH ou a expressão regular REGEXP_CONTAINS precisa ter texto suficiente para pelo menos um n-grama. Por exemplo, r".*" não se qualifica porque não há uma sequência de caracteres para corresponder. Da mesma forma, se o tamanho mínimo do n-grama for definido como 3, o predicado LIKE "%ab%" não se qualificará porque "ab" (tamanho 2) é muito curto.

A seguir