17

我最近一直在优化我的 Postgres 数据库,而传统上,我只使用过 B-Tree 索引。但是,我在 Postgres 8.3 文档中看到 GiST 索引支持非唯一的多列索引。

但是,我看不出它们之间的实际区别是什么。我希望我的程序员同事能够解释它们之间的优缺点,更重要的是,为什么我会使用其中一个而不是另一个?

4

4 回答 4

23

简而言之:B-Tree 索引性能更好,但 GiST 索引更灵活。通常,如果 B-Tree 索引适用于您的数据类型,则需要它们。PG 列表上最近有一篇关于使用 GiST 索引对性能造成巨大影响的帖子;预计它们会比 B-Trees 慢(这就是灵活性的代价),但不会很多……正如您所料,工作正在进行中。

来自PostgreSQL 核心开发人员Tom Lane 的帖子:

GIST 的要点是能够索引在 btree 中根本不可索引的查询。...人们完全期望 btree 在 btree 可索引案例中击败 GIST。我认为这里重要的一点是它赢了几百倍。这非常糟糕,并且可能指向一些实现问题。

于 2009-04-20T00:33:17.843 回答
6

基本上每个人都是对的 - btree 是默认索引,因为它执行得非常好。GiST 有点不同——它更像是一个“编写索引类型的框架”,而不是一个索引类型。您必须添加自定义代码(在服务器中)才能使用它,但另一方面 - 它们非常灵活。

通常 - 您不使用 GiST,除非您使用的数据类型告诉您这样做。使用 GiST 的数据类型示例:ltree(来自 contrib)、tsvector(contrib/tsearch 直到 8.2,自 8.3 开始在核心)等。

众所周知,PostgreSQL 的地理扩展速度非常快 - PostGIS ( http://postgis.refractions.net/ ),它使用 GiST 来实现其目的。

于 2009-04-20T04:52:47.550 回答
2

GiST 索引在一定程度上是有损的,这意味着 DBMS 必须处理误报/误报,即:

GiST 索引是有损的,因为每个文档在索引中都由固定长度的签名表示。签名是通过将每个单词散列成 n 位字符串中的一个随机位生成的,所有这些位 OR-ed 一起产生一个 n 位文档签名。当两个单词散列到相同的位位置时,将出现错误匹配。如果查询中的所有单词都匹配(真或假),则必须检索表行以查看匹配是否正确。b-trees 没有这种行为,因此根据被索引的数据,两者之间可能存在一些性能差异。

有关文本搜索行为,请参见http://www.postgresql.org/docs/8.3/static/textsearch-indexes.htmlhttp://www.postgresql.org/docs/8.3/static/indexes-types.html通用比较。

于 2009-04-20T00:30:34.043 回答
2

GiST 是更通用的索引。您可以将它们用于与 B-Tree 一起使用的更广泛的用途。包括使用 GiST 构建 B-Tree 的能力。

IE:您可以使用 GiST 对地理点或地理区域进行索引,这是您无法使用 B-Tree 索引做的事情,因为 B-Tree 上唯一重要的是您的键(或键)正在建立索引。

于 2009-04-20T00:31:11.157 回答