Spanner 検索インデックスを使用すると、LIKE、STARTS_WITH、ENDS_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 では、LIKE、STARTS_WITH、ENDS_WITH、REGEXP_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 では、LIKE と STARTS_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)が短すぎるため、条件を満たしません。
次のステップ
- ファジー検索で近似一致を見つける方法を確認する。