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);
自动加快使用模式匹配谓词的查询的速度
查询优化器可能会选择使用带有 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列。这样可以防止在后过滤期间对基表进行代价高昂的后向联接,这对于搜索过度检索文档时的性能至关重要。 - 必须使用
TOKENIZE_NGRAMS对STRING列进行分词。 - 分词必须应用于
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)太短。
后续步骤
- 了解如何使用模糊搜索查找近似匹配项。