支持的版本:当前 (17) / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

12.2. 表和索引 #

上一节中的示例说明了使用简单常量字符串进行全文匹配。本节展示如何搜索表数据,可以选择使用索引。

12.2.2. 创建索引 #

我们可以创建一个GIN索引(第 12.9 节)以加速文本搜索

CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', body));

请注意,使用了to_tsvector的2参数版本。只有指定配置名称的文本搜索函数才能在表达式索引中使用(第 11.7 节)。这是因为索引内容不能受 default_text_search_config的影响。如果受到影响,索引内容可能会不一致,因为不同的条目可能包含使用不同的文本搜索配置创建的tsvector,并且无法猜测哪个是哪个。将不可能正确地转储和还原这样的索引。

由于在上面的索引中使用了to_tsvector的两个参数版本,因此只有使用to_tsvector的两个参数版本且配置名称相同的查询引用才会使用该索引。也就是说,WHERE to_tsvector('english', body) @@ 'a & b'可以使用该索引,但是WHERE to_tsvector(body) @@ 'a & b'不能。这样可以确保索引仅与用于创建索引条目的配置一起使用。

可以设置更复杂的表达式索引,其中配置名称由另一个列指定,例如

CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector(config_name, body));

其中config_namepgweb表中的一列。这允许在同一索引中使用混合配置,同时记录每个索引条目使用了哪个配置。例如,如果文档集合包含不同语言的文档,这将非常有用。同样,旨在使用索引的查询必须措辞匹配,例如,WHERE to_tsvector(config_name, body) @@ 'a & b'

索引甚至可以连接列

CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' || body));

另一种方法是创建一个单独的tsvector列来保存to_tsvector的输出。要使此列与其源数据自动保持最新,请使用存储的生成列。此示例是titlebody的串联,使用coalesce来确保当另一个字段为NULL时,仍会索引一个字段

ALTER TABLE pgweb
    ADD COLUMN textsearchable_index_col tsvector
               GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body, ''))) STORED;

然后我们创建一个GIN索引以加快搜索速度

CREATE INDEX textsearch_idx ON pgweb USING GIN (textsearchable_index_col);

现在我们准备好执行快速全文搜索

SELECT title
FROM pgweb
WHERE textsearchable_index_col @@ to_tsquery('create & table')
ORDER BY last_mod_date DESC
LIMIT 10;

与表达式索引相比,单独列方法的一个优点是不必在查询中显式指定文本搜索配置即可使用索引。如上面的示例所示,查询可以依赖于default_text_search_config。另一个优点是搜索速度更快,因为无需重做to_tsvector调用来验证索引匹配。(当使用 GiST 索引而不是 GIN 索引时,这更为重要;请参见第 12.9 节。)但是,表达式索引方法更易于设置,并且需要更少的磁盘空间,因为tsvector表示形式不会显式存储。

提交更正

如果您在文档中发现任何不正确的内容,与您使用特定功能的经验不符或需要进一步说明的内容,请使用此表单报告文档问题。