Postgresql

雜湊索引怎麼可能不比 Btree 更快地進行相等查找?

  • December 18, 2020

對於每個支持散列索引的 Postgres 版本,都有一個警告或說明散列索引比btree索引“相似或慢”或“不是更好”,至少到版本 8.3。從文件:

7.2 版

注意:由於散列索引的實用性有限,通常應該優先使用 B 樹索引而不是散列索引。即使對於 = 比較,我們也沒有足夠的證據表明雜湊索引實際上比 B 樹更快。此外,雜湊索引需要更粗的鎖;見第 9.7 節。

7.3 版(以及最高 8.2 版)

注意:測試表明 PostgreSQL 的雜湊索引與 B-tree 索引相似或慢,並且雜湊索引的索引大小和建構時間要差得多。雜湊索引在高並發下也表現不佳。由於這些原因,不鼓勵使用雜湊索引。

8.3 版

注意:測試表明 PostgreSQL 的雜湊索引的性能並不比 B-tree 索引好,而且雜湊索引的索引大小和建構時間要差得多。此外,雜湊索引操作目前沒有 WAL 日誌記錄,因此在數據庫崩潰後可能需要使用 REINDEX 重建雜湊索引。由於這些原因,目前不鼓勵使用散列索引。

在這個 8.0 版執行緒中,他們聲稱從未發現雜湊索引實際上比 btree 更快的情況。

根據這篇博文(2016 年 3 月 14 日):André Barbosa

的 Postgres 上的雜湊索引,即使在 9.2 版中,除了編寫實際索引之外的任何性能提升幾乎都沒有。

我的問題是這怎麼可能?

根據定義,雜湊索引是一種O(1)操作,而 btree 是一種O(log n)操作。那麼O(1)查找如何可能比(甚至類似於)找到正確的分支慢,然後找到正確的記錄呢?

我想知道索引理論如何使這種可能性成為可能!

基於磁碟的 Btree 索引確實是 O(log N),但這與適合這個太陽系的磁碟陣列幾乎無關。由於記憶體,它們大多是 O(1) 和一個非常大的常數加上 O((log N)-1) 和一個小常數。形式上,這與 O(log N) 相同,因為常量在大 O 表示法中並不重要。但它們在現實中確實很重要。

雜湊索引查找的大部分放緩來自於需要防止由於雜湊表大小調整與查找並發造成的損壞或死鎖。直到最近的版本(你提到的每個版本都過時了),這種需求導致更高的常量和相當差的並發性。與雜湊並發相比,BTree 並發優化的工時要多得多。

引用自:https://dba.stackexchange.com/questions/212685