PostgreSQL 哈希索引

Posted

技术标签:

【中文标题】PostgreSQL 哈希索引【英文标题】:PostgreSQL HASH index 【发布时间】:2010-09-28 18:31:56 【问题描述】:

有谁知道应该使用 PostgreSQL HASH 而不是 B-TREE 的情况,因为在我看来这些东西是一个陷阱。它们比 B-TREE 花费更多的时间来创建或维护(至少多 10 倍),它们还占用更多空间(对于我的一个 table.columns,B-TREE 占用 240 MB,而 HASH 会占用 4 GB),我似乎从我的谷歌搜索中了解到,它们的 SELECT 速度并不比 B-TREE 快;然而 HASH 可能最近已经优化或者谷歌是错误的。

无论如何,我想要你们的意见和经验。如果这些 HASH 是邪恶的,人们应该知道。

谢谢 另外:mysql 的 HASH 呢?

【问题讨论】:

【参考方案1】:

最好对仅使用 = 运算符搜索的文本列使用哈希索引。例如,需要为查找建立索引的 URL 列。

对于诸如 URL 之类的东西,哈希索引大约是 B-Tree 索引大小的 30%。

减小的大小允许 PostgreSQL 更有效地使用它的缓存内存(又名 shared_buffers)。

【讨论】:

【参考方案2】:

对于具有已知键值(尤其是已知唯一值)的情况,哈希比 B 树更快。

如果有问题的列从不打算用<>命令进行比较扫描,则应使用哈希。

哈希是O(1) 复杂度,B 树是O(log n) 复杂度(iirc),因此,对于具有唯一条目的大型表,获取ITEM="foo",它们将是查找它的最有效方式。

当这些唯一字段用于连接条件时,这尤其实用。

【讨论】:

确实,这几乎是我在研究 PostgreSQL 开发人员的观点之前的想法。但似乎即使对于您描述的情况,HASH 在效率和有效性方面也没有超过 B-TREE,因为理论上的算法似乎不太实用。谢谢 应该注意的是,从 8.4 版开始,哈希索引比 b-tree 索引效率低且速度慢的问题已得到解决。 postgresql.org/docs/8.4/static/release-8-4.html#AEN95616 只有一个问题,据我所知,二叉树搜索是 O(logn),而不是 O(n*logn),对吗? O(1) 在内存中,但是对于数据库,数据通常在磁盘上,索引也可能在磁盘上,磁盘访问时间>> RAM访问时间。我不记得从数据库类中确切地说这是如何工作的,但在某些情况下它不是O(1)。我仍然希望 hash 会快得多,但在 Postgres 9.5 中,hash 据报道仅比 b-tree 快一点,而且它也不是完全安全的。 是的。事实上,你很少能得到“真实世界”的恒定时间性能,在事物的背后总有一些现实让事情变得困难。就像,内存访问可能是O(1),但取决于您谈论的内存,1 的值可能非常大或非常小;)。 L1/L2/L3/Ram/Swap速度不都一样,但算法本身还是算O(1)【参考方案3】:

我还没有尝试过,但正在考虑这种方法,在未记录的临时表上使用哈希索引。

我的理解是,它们构建速度更快,占用空间更少,查询速度略快于 b-tree。

根据this benchmark,哈希索引比 BTree 索引要快一些,但要小一些。但是,你不能用它们创建一个唯一的哈希索引——另外它们不是 WAL 记录的。

【讨论】:

【参考方案4】:

由于http://www.postgresql.org/docs/9.2/static/sql-createindex.html 点哈希索引仍然不是 WAL 安全的;这意味着它们对于崩溃不是 100% 可靠的(必须重建索引,并且在复制时可能会发生错误的响应)。还要检查http://www.postgresql.org/docs/9.1/static/wal-intro.html

【讨论】:

这对于流式复制或基于文件的复制也是如此,并且在 9.5 版中仍然如此。 postgresql.org/docs/9.5/static/indexes-types.html 从 v10 起不再适用。 enterprisedb.com/blog/postgresqls-hash-indexes-are-now-cool

以上是关于PostgreSQL 哈希索引的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 哈希索引

MySQL之哈希索引

mysql-哈希索引

B+树索引和哈希索引的区别

自适应哈希索引

MySQL中自适应哈希索引