Mempercepat ekspresi pencocokan pola

Indeks penelusuran Spanner dapat mempercepat ekspresi pencocokan pola seperti LIKE, STARTS_WITH, ENDS_WITH, dan predikat pencocokan ekspresi reguler REGEXP_CONTAINS. Halaman ini menjelaskan cara membuat dan mengonfigurasi indeks penelusuran menggunakan TOKENIZE_NGRAMS untuk mempercepat predikat pencocokan pola.

Mengonfigurasi n-gram TOKENLIST untuk akselerasi pencocokan pola

Untuk mengaktifkan akselerasi ekspresi pencocokan pola, tokenisasi kolom STRING huruf kecil dengan TOKENIZE_NGRAMS dan simpan kolom STRING menggunakan klausa STORING di GoogleSQL, atau klausa INCLUDE di 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);

Percepatan otomatis kueri dengan predikat pencocokan pola

Pengoptimal kueri dapat memilih untuk mempercepat kueri berikut menggunakan AlbumsIndex dengan AlbumTitle_Ngram_Tokens. Secara opsional, kueri dapat memberikan @{force_index = AlbumsIndex} untuk memaksa pengoptimal menggunakan AlbumsIndex.

GoogleSQL

Di GoogleSQL, kita mempercepat LIKE, STARTS_WITH, ENDS_WITH, dan REGEXP_CONTAINS.

  • Predikat LIKE:

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

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

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

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

PostgreSQL

Di PostgreSQL, kita mempercepat LIKE dan STARTS_WITH.

  • Predikat LIKE:

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

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

Prasyarat untuk akselerasi

Agar Spanner dapat mengaktifkan akselerasi ini, aturan berikut harus dipenuhi:

  • Indeks harus menyimpan kolom STRING menggunakan klausa STORING di GoogleSQL, atau klausa INCLUDE di PostgreSQL. Hal ini mencegah penggabungan kembali yang mahal ke tabel dasar selama pemfilteran pasca-pemfilteran, yang sangat penting untuk performa saat penelusuran mengambil dokumen secara berlebihan.
  • Kolom STRING harus di-tokenisasi menggunakan TOKENIZE_NGRAMS.
  • Tokenisasi harus berlaku untuk LOWER(column_name), bukan column_name.
  • Pola LIKE, awalan STARTS_WITH, akhiran ENDS_WITH, atau ekspresi reguler REGEXP_CONTAINS harus ditentukan sebagai literal konstanta. Parameter kueri tidak didukung untuk menghindari akselerasi pada pola yang terlalu pendek.
  • Pola LIKE, awalan STARTS_WITH, akhiran ENDS_WITH, atau ekspresi reguler REGEXP_CONTAINS harus berisi cukup teks untuk setidaknya satu n-gram. Misalnya, r".*" tidak memenuhi syarat karena tidak ada urutan karakter yang cocok. Demikian pula, jika ukuran minimum ngram ditetapkan ke 3, predikat LIKE "%ab%" tidak memenuhi syarat karena "ab" (ukuran 2) terlalu pendek.

Langkah berikutnya