Spanner 搜索索引可以加快模式匹配表达式(例如 LIKE、STARTS_WITH、ENDS_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);
自动加速使用模式匹配谓词的查询
查询优化器可能会选择使用 AlbumsIndex 和 AlbumTitle_Ngram_Tokens 加速以下查询。查询可以选择性地提供 @{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进行分词。- 分词必须应用于
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)太短。
后续步骤
- 了解如何使用模糊搜索查找近似匹配项。