我最近一直在努力优化我的Postgres数据库,传统上,我只使用B-Tree索引。但是,我在Postgres 8.3文档中看到GiST索引支持非唯一的多列索引。
但是,我不能看出它们之间的实际区别是什么。我希望我的同事们能够解释一下,他们之间的利弊是什么,更重要的是,我之所以使用其中一个的原因是什么?答案 0 :(得分:22)
简而言之:B-Tree索引的性能更好,但GiST索引更灵活。通常,如果B-Tree索引适用于您的数据类型,则需要它们。 PG名单上最近有一篇关于使用GiST索引的巨大性能损失的帖子;他们预计会比B-Trees慢(这就是灵活性的代价),但不会 慢得多......正如你所料,工作正在进行中。
来自a post by Tom Lane,一个核心PostgreSQL开发人员:
GIST的要点是能够索引简单的查询 在btree中无法索引。 ......一个人会完全 期待btree为btree-indexable案件击败GIST。我觉得 这里的重点是,它赢得了一对夫妇 百;这非常糟糕,可能会指出一些实现 问题
答案 1 :(得分:5)
基本上每个人都是对的 - btree是默认索引,因为它表现得非常好。 GiST是一些不同的野兽 - 它更像是一个“编写索引类型的框架”,而不是一个索引类型。您必须添加自定义代码(在服务器中)才能使用它,但另一方面 - 它们非常灵活。
通常 - 除非您使用的数据类型告诉您这样做,否则不使用GiST。使用GiST的数据类型示例:ltree(来自contrib),tsvector(contrib / tsearch至8.2,自8.3以来的核心)以及其他。
PostgreSQL有着众所周知且快速的地理扩展 - PostGIS(http://postgis.refractions.net/),它将GiST用于其目的。
答案 2 :(得分:3)
GiST索引在某种程度上是有损的,这意味着DBMS必须处理误报/否定,即:
GiST索引是有损的,因为每个文档都在索引中以固定的方式表示 - 长度签名。签名是 通过将每个单词散列到一个单词中生成 n位字符串中的随机位,带 所有这些位OR-ed一起 产生一个n位文档签名。 当两个单词哈希到同一位时 位置会有一个错误的匹配。 如果查询中的所有单词都匹配 (真或假)然后表行 必须检索以查看是否匹配 是正确的。 b-tree没有这种行为,因此根据被索引的数据,两者之间可能存在一些性能差异。
有关常规比较的信息,请参阅文字搜索行为http://www.postgresql.org/docs/8.3/static/textsearch-indexes.html和http://www.postgresql.org/docs/8.3/static/indexes-types.html。
答案 3 :(得分:2)
GiST是更通用的索引。您可以将它们用于与B-Tree一起使用的更广泛的目的。包括使用GiST构建B树的能力。
IE:您可以使用GiST来索引地理点或地理区域,这是B-Tree索引无法做到的事情,因为B树上唯一重要的是键(或者键)你正在索引。