Acelere as expressões de correspondência de padrões

Os índices de pesquisa do Spanner podem acelerar as 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. Esta página descreve como criar e configurar um índice de pesquisa usando TOKENIZE_NGRAMS para acelerar os predicados de correspondência de padrões.

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

Para ativar a aceleração de expressões de correspondência de padrões, tokenizar uma coluna STRING com letras minúsculas usando TOKENIZE_NGRAMS e armazenar a coluna STRING usando a cláusula STORING no GoogleSQL ou a cláusula 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 optar por acelerar as seguintes consultas através de AlbumsIndex com AlbumTitle_Ngram_Tokens. Opcionalmente, 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 na aceleração

Para que o Spanner ative esta aceleração, têm de ser cumpridas as seguintes regras:

  • O índice tem de armazenar a coluna STRING usando a cláusula STORING no GoogleSQL ou a cláusula INCLUDE no PostgreSQL. Isto evita junções posteriores dispendiosas à tabela base durante a filtragem posterior, o que é fundamental para o desempenho quando a pesquisa obtém documentos em excesso.
  • A coluna STRING tem de ser tokenizada através de TOKENIZE_NGRAMS.
  • A tokenização tem de ser aplicada a LOWER(column_name) e não a column_name.
  • O padrão LIKE, o prefixo STARTS_WITH, o sufixo ENDS_WITH ou a expressão regular REGEXP_CONTAINS tem de ser especificado como um literal constante. Os parâmetros de consulta não são suportados para evitar a aceleração em padrões demasiado curtos.
  • O padrão LIKE, o prefixo STARTS_WITH, o sufixo ENDS_WITH ou a expressão regular REGEXP_CONTAINS têm de conter texto suficiente para, pelo menos, um n-grama. Por exemplo, r".*" não se qualifica porque não existe uma sequência de carateres para corresponder. Da mesma forma, se o tamanho mínimo do n-grama estiver definido como 3, o predicado LIKE "%ab%" não se qualifica porque "ab" (tamanho 2) é demasiado curto.

O que se segue?