パターン マッチング式を高速化する

Spanner 検索インデックスを使用すると、LIKESTARTS_WITHENDS_WITH などのパターン マッチング式や、正規表現マッチング述語 REGEXP_CONTAINS を高速化できます。このページでは、TOKENIZE_NGRAMS を使用して検索インデックスを作成して構成し、パターン マッチング述語を高速化する方法について説明します。

パターン マッチングの高速化のために n グラム TOKENLIST を構成する

パターン マッチング式の高速化を有効にするには、小文字の STRING 列を TOKENIZE_NGRAMS でトークン化し、GoogleSQL の STORING 句または PostgreSQL の INCLUDE 句を使用して STRING 列を保存します。

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

パターン マッチング述語を使用したクエリの自動高速化

クエリ オプティマイザーは、AlbumTitle_Ngram_Tokens を含む AlbumsIndex を使用して、次のクエリを高速化する場合があります。必要に応じて、クエリで @{force_index = AlbumsIndex} を指定して、オプティマイザーに AlbumsIndex の使用を強制できます。

GoogleSQL

GoogleSQL では、LIKESTARTS_WITHENDS_WITHREGEXP_CONTAINS を高速化します。

  • LIKE 述語:

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

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

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

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

PostgreSQL

PostgreSQL では、LIKESTARTS_WITH を高速化します。

  • LIKE 述語:

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

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

アクセラレーションの前提条件

Spanner でこの高速化を有効にするには、次のルールを満たす必要があります。

  • インデックスは、GoogleSQL の STORING 句または PostgreSQL の INCLUDE 句を使用して STRING 列を保存する必要があります。これにより、検索でドキュメントが過剰に取得された場合にパフォーマンスに不可欠な、フィルタ後のベーステーブルへのコストのかかるバック結合を防ぐことができます。
  • STRING 列は TOKENIZE_NGRAMS を使用してトークン化する必要があります。
  • トークン化は column_name ではなく LOWER(column_name) に適用する必要があります。
  • LIKE パターン、STARTS_WITH 接頭辞、ENDS_WITH 接尾辞、または REGEXP_CONTAINS 正規表現は、定数リテラルとして指定する必要があります。短すぎるパターンでの加速を回避するため、クエリ パラメータはサポートされていません。
  • LIKE パターン、STARTS_WITH プレフィックス、ENDS_WITH サフィックス、または REGEXP_CONTAINS 正規表現には、少なくとも 1 つの n グラムに十分なテキストが含まれている必要があります。たとえば、一致する文字列のシーケンスがないため、r".*" は条件を満たしません。同様に、ngram の最小サイズが 3 に設定されている場合、LIKE 述語 "%ab%""ab"(サイズ 2)が短すぎるため、条件を満たしません。

次のステップ