2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 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.9. 文本搜索的首选索引类型 #

有两种索引可以用来加速全文搜索:GINGiST。请注意,索引对于全文搜索不是强制性的,但如果在列上经常进行搜索,则通常需要索引。

要创建这样的索引,请执行以下操作之一:

CREATE INDEX name ON table USING GIN (column);

创建一个基于 GIN(广义倒排索引)的索引。 column 必须是 tsvector 类型。

CREATE INDEX name ON table USING GIST (column [ { DEFAULT | tsvector_ops } (siglen = number) ] );

创建一个基于 GiST(广义搜索树)的索引。 column 可以是 tsvectortsquery 类型。可选的整数参数 siglen 决定了签名的长度(以字节为单位,详见下文)。

GIN 索引是首选的文本搜索索引类型。作为倒排索引,它们为每个词(词素)包含一个索引条目,以及一个匹配位置的压缩列表。多词搜索可以找到第一个匹配项,然后使用索引删除缺少附加词的行。GIN 索引仅存储 tsvector 值中的词(词素),而不存储它们的权重标签。因此,在使用涉及权重的查询时,需要重新检查表行。

GiST 索引是 有损的,这意味着索引可能会产生误匹配,并且有必要检查实际的表行以消除这些误匹配。(PostgreSQL 在需要时会自动执行此操作。)GiST 索引之所以有损,是因为每个文档在索引中都由一个固定长度的签名表示。签名长度(以字节为单位)由可选的整数参数 siglen 决定。默认签名长度(未指定 siglen 时)为 124 字节,最大签名长度为 2024 字节。签名是通过将每个单词散列到 n 位字符串的一个位中生成的,所有这些位都通过 OR 运算组合在一起以产生一个 n 位文档签名。当两个单词散列到同一位位置时,会发生误匹配。如果查询中的所有单词都有匹配项(真实或误匹配),则必须检索表行以查看匹配项是否正确。更长的签名会带来更精确的搜索(扫描更小比例的索引和更少的堆页),但代价是索引更大。

GiST 索引可以是覆盖索引,即使用 INCLUDE 子句。包含的列可以是没有任何 GiST 操作符类的任何数据类型。包含的属性将以未压缩的形式存储。

有损性会导致性能下降,因为会不必要地获取最终证明是误匹配的表记录。由于对表记录的随机访问速度很慢,这限制了 GiST 索引的实用性。误匹配的可能性取决于几个因素,特别是唯一单词的数量,因此建议使用字典来减少这个数量。

请注意:GIN通过增加 maintenance_work_mem 可以经常提高索引构建时间,而GiST索引构建时间不受该参数的影响。

大型集合的分区以及 GIN 和 GiST 索引的正确使用,可以实现非常快速的在线更新搜索。分区可以通过数据库级别的表继承来实现,或者通过在服务器之间分发文档并通过外部搜索结果收集,例如通过 外部数据 访问来实现。后者是可能的,因为排名函数只使用本地信息。

提交更正

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