文本搜索的GiST和GIN索引

文本搜索的GiST和GIN索引

本主题描述并比较用于全文搜索的Greenplum数据库索引类型。

有两种索引可用于加速全文搜索。 索引对于全文搜索不是强制性的,但是在定期搜索列的情况下,通常需要索引。

CREATE INDEX name ON table USING gist(column);

创建基于GiST(广义搜索树)的索引。 该列可以是tsvectortsquery类型。

CREATE INDEX name ON table USING gin(column);

创建基于GIN(广义倒置索引)的索引。 该列必须是tsvector类型。

两种索引类型之间存在显着的性能差异,因此了解它们的特征非常重要。

GiST索引是有损的,这意味着索引可能产生错误匹配,并且有必要检查实际的表行以消除这种错误匹配。 (Greenplum数据库在需要时自动执行此操作。)GiST索引是有损的,因为每个文档在索引中由固定长度签名表示。 通过将每个字散列为n比特串中的单个比特来生成签名,所有这些比特一起做OR产生n比特文档签名。 当两个单词散列到相同的位位置时,将存在错误匹配。 如果查询中的所有单词都匹配(真或假),则必须检索表行以查看匹配是否正确。

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

对于标准查询,GIN索引不是有损的,但它们的性能取决于唯一字数量的对数。 (但是,GIN索引只存储tsvector值的单词(词位),而不存储它们的权重标签。 因此,当使用涉及权重的查询时,需要重新检查表行。)

在选择要使用的索引类型,GiST或GIN时,请考虑以下性能差异:

  • GIN索引查找速度比GiST快三倍
  • GIN索引的构建时间比GiST长大约三倍
  • GIN索引的更新速度比GiST索引要慢,但如果禁用快速更新支持,速度会慢10倍(有关详细信息,请参阅PostgreSQL文档中的GIN快速更新技术
  • GIN索引比GiST索引大两到三倍

根据经验,GIN索引最适合静态数据,因为查找速度更快。 对于动态数据,GiST索引的更新速度更快。 具体来说,GiST索引非常适合动态数据,如果唯一单词(词位)的数量低于100,000,则快速,而GIN索引将更好地处理100,000+词位,但更新速度较慢。

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

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