Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

12.9. 文本搜索的首选索引类型 #

有两种索引可用于加速全文搜索:GINGiST。请注意,索引对于全文搜索不是必需的,但在定期搜索某一列的情况下,通常需要一个索引。

要创建此类索引,请执行以下操作之一

CREATE INDEX 名称 ON USING GIN ();

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

CREATE INDEX 名称 ON USING GIST ( [ { DEFAULT | tsvector_ops } (siglen = 数字) ] );

创建一个基于 GiST(广义搜索树)的索引。 可以为 tsvectortsquery 类型。可选的整数参数 siglen 确定签名长度(以字节为单位)(有关详细信息,请参见下文)。

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

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

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

由于不必要的表记录获取(结果证明是错误匹配)会导致性能下降,因此会造成信息丢失。由于对表记录的随机访问很慢,因此这限制了 GiST 索引的实用性。错误匹配的可能性取决于多个因素,特别是唯一单词的数量,因此建议使用词典来减少此数量。

请注意,通常可以通过增加 maintenance_work_mem 来改善 GIN 索引的构建时间,而 GiST 索引的构建时间对此参数不敏感。

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