Accelerare le espressioni di corrispondenza di pattern

Gli indici di ricerca di Spanner possono accelerare le espressioni di corrispondenza di pattern come LIKE, STARTS_WITH, ENDS_WITH, e il predicato di corrispondenza di espressioni regolari REGEXP_CONTAINS. Questa pagina descrive come creare e configurare un indice di ricerca utilizzando TOKENIZE_NGRAMS per accelerare i predicati di corrispondenza di pattern.

Configurare un TOKENLIST n-gram per l'accelerazione della corrispondenza di pattern

Per abilitare l'accelerazione delle espressioni di corrispondenza di pattern, tokenizza una colonna in minuscolo STRING con TOKENIZE_NGRAMS e memorizza la colonna STRING utilizzando la clausola STORING in GoogleSQL o la clausola INCLUDE in 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);

Accelerazione automatica delle query con predicati di corrispondenza di pattern

L'ottimizzatore di query potrebbe scegliere di accelerare le seguenti query utilizzando AlbumsIndex con AlbumTitle_Ngram_Tokens. Facoltativamente, la query può fornire @{force_index = AlbumsIndex} per forzare l'ottimizzatore a utilizzare AlbumsIndex.

GoogleSQL

In GoogleSQL, acceleriamo LIKE, STARTS_WITH, ENDS_WITH, e REGEXP_CONTAINS.

  • Predicato LIKE:

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

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

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

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

PostgreSQL

In PostgreSQL, acceleriamo LIKE e STARTS_WITH.

  • Predicato LIKE:

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

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

Prerequisiti per l'accelerazione

Affinché Spanner possa abilitare questa accelerazione, devono essere soddisfatte le seguenti regole:

  • L'indice deve memorizzare la colonna STRING utilizzando la clausola STORING in GoogleSQL o la clausola INCLUDE in PostgreSQL. In questo modo si evitano costosi join inversi alla tabella di base durante il post-filtraggio, il che è fondamentale per le prestazioni quando la ricerca recupera eccessivamente i documenti.
  • La colonna STRING deve essere tokenizzata utilizzando TOKENIZE_NGRAMS.
  • La tokenizzazione deve essere applicata a LOWER(column_name) anziché a column_name.
  • Il LIKE pattern, STARTS_WITH prefisso, ENDS_WITH suffisso o l'espressione REGEXP_CONTAINS regolare devono essere specificati come un valore letterale costante. I parametri di query non sono supportati per evitare l'accelerazione su pattern troppo brevi.
  • Il LIKE pattern, STARTS_WITH prefisso, ENDS_WITH suffisso o REGEXP_CONTAINS espressione regolare devono contenere testo sufficiente per almeno un n-gramma. Ad esempio r".*" non è idoneo perché non esiste una sequenza di caratteri da trovare. Allo stesso modo, se la dimensione minima dell'n-gramma è impostata su 3, il LIKE predicato "%ab%" non è idoneo perché "ab" (dimensione 2) è troppo breve.

Passaggi successivi