加速模式匹配表达式

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

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

查询优化器可能会选择使用带有 AlbumTitle_Ngram_TokensAlbumsIndex 来加快以下查询的速度。或者,查询可以提供 @{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 列。这样可以防止在后过滤期间对基表进行代价高昂的后向联接,这对于搜索过度检索文档时的性能至关重要。
  • 必须使用 TOKENIZE_NGRAMSSTRING列进行分词。
  • 分词必须应用于 LOWER(column_name),而不是 column_name
  • LIKE 模式、 STARTS_WITH 前缀、 ENDS_WITH 后缀或 REGEXP_CONTAINS 正则表达式必须指定为常量字面量。不支持查询参数 ,以避免对过短的模式进行加速。
  • LIKE 模式、 STARTS_WITH 前缀、 ENDS_WITH 后缀或 REGEXP_CONTAINS 正则表达式必须包含足够的文本,以便至少包含一个 N 元语法。例如, r".*" 不符合条件,因为没有要匹配的字符序列 。同样,如果 n-gram 最小大小设置为 3,则 LIKE 谓词 "%ab%" 不符合条件,因为 "ab"(大小为 2)太短。

后续步骤