12.9. GIN 和 GiST 索引类型

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

  • CREATE INDEX name ON table USING GIN (column);

    • 创建基于 GIN(广义反向索引)的索引。 * column *必须为tsvector类型。
  • CREATE INDEX name ON table USING GIST (column);

    • 创建基于 GiST(通用搜索树)的索引。 * column *可以是tsvectortsquery类型。

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

GiST 索引是* lossy *,这意味着索引可能会产生错误匹配,因此有必要检查实际的表行以消除此类错误匹配。 (PostgreSQL 会在需要时自动执行此操作.)GiST 索引是有损的,因为索引中的每个文档都由固定长度的签名表示。签名是通过将每个单词散列为 n 位字符串中的单个位而生成的,所有这些位进行“或”运算以生成 n 位文档签名。当两个单词散列到相同的位位置时,将出现错误匹配。如果查询中的所有单词都匹配(真或假),则必须检索表行以查看匹配是否正确。

由于不必要地提取了表记录而导致虚假匹配,因此损失会导致性能下降。由于对表记录的随机访问很慢,因此这限制了 GiST 索引的用途。错误匹配的可能性取决于多个因素,尤其是唯一单词的数量,因此建议使用字典来减少该数量。

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

对大集合进行分区以及正确使用 GIN 和 GiST 索引,可以通过在线更新实现非常快速的搜索。可以使用表继承在数据库级别进行分区,也可以通过在服务器上分发文档并使用dblink模块收集搜索结果来进行分区。后者是可能的,因为排名功能仅使用本地信息。