加速模式匹配表达式

Spanner 搜索索引可以加快模式匹配表达式(例如 LIKESTARTS_WITHENDS_WITH)和正则表达式匹配谓词 REGEXP_CONTAINS 的执行速度。本页面介绍了如何使用 TOKENIZE_NGRAMS 创建和配置搜索索引,以加快模式匹配谓词的速度。

配置用于加快模式匹配速度的 n-gram TOKENLIST

如需启用模式匹配表达式加速功能,请使用 TOKENIZE_NGRAMS 对小写的 STRING 列进行分词,并使用 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);

自动加速使用模式匹配谓词的查询

查询优化器可能会选择使用 AlbumsIndexAlbumTitle_Ngram_Tokens 加速以下查询。查询可以选择性地提供 @{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 进行分词。
  • 分词必须应用于 LOWER(column_name),而不是 column_name
  • LIKE 模式、STARTS_WITH 前缀、ENDS_WITH 后缀或 REGEXP_CONTAINS 正则表达式必须指定为常量字面量。不支持查询参数,以避免对过短的模式进行加速。
  • LIKE 模式、STARTS_WITH 前缀、ENDS_WITH 后缀或 REGEXP_CONTAINS 正则表达式必须包含足够的文本,以形成至少一个 n-gram。例如,r".*" 不符合条件,因为没有要匹配的字符序列。同样,如果将 n-gram 最小大小设置为 3,则 LIKE 谓词 "%ab%" 不符合条件,因为 "ab"(大小为 2)太短。

后续步骤