hashインデックスをサポートしたPostgresのすべてのバージョンについて、ハッシュインデックスがbtreeインデックスよりも「類似または遅い」または「良くない」、少なくともバージョン8.3まで。ドキュメントから:
バージョン7.2 :
注:ハッシュインデックスのユーティリティは制限されているため、通常はハッシュインデックスよりもBツリーインデックスを優先する必要があります。 =比較の場合でも、ハッシュインデックスが実際にBツリーよりも速いことを示す十分な証拠はありません。さらに、ハッシュインデックスにはより粗いロックが必要です。セクション9.7を参照してください。
注:テストにより、PostgreSQLのハッシュインデックスはBツリーインデックスよりも似ているか遅いことがわかり、ハッシュインデックスのインデックスサイズとビルド時間ははるかに悪い。また、同時実行性が高いと、ハッシュインデックスのパフォーマンスが低下します。これらの理由により、ハッシュインデックスの使用はお勧めしません。
バージョン8. :
注:テストの結果、PostgreSQLのハッシュインデックスはBツリーインデックスよりもパフォーマンスが優れていることが示されています。また、ハッシュインデックスのインデックスサイズとビルド時間ははるかに長くなります。さらに、ハッシュインデックス操作は現在WALログに記録されていないため、データベースクラッシュ後にハッシュインデックスをREINDEXで再構築する必要がある場合があります。これらの理由により、ハッシュインデックスの使用は現在推奨されていません。
このバージョン8.0のスレッドでは 、彼らは、ハッシュインデックスが実際にbtreeよりも高速であるケースを見つけたことはないと主張しています。
このブログ投稿(2016年3月14日)によると、バージョン9.2でも、実際のインデックスを作成する以外のパフォーマンスの向上はほとんどありません。
Postgresのハッシュインデックス、AndréBarbosa著。
私の質問はそれはどうして可能ですか?
定義により、ハッシュインデックスはO(1)
操作であり、btreeはO(log n)
操作です。では、どのようにO(1)
ルックアップが正しいブランチを見つけてから正しいレコードを見つけるよりも遅い(またはそれに似ている)のはどうして可能でしょうか。
索引付け理論について、それを可能にすることは決してありません。
ディスクベースのBtreeインデックスはO(log N)ですが、このソーラーシステムに適合するディスクアレイにはほとんど関係ありません。キャッシングのため、それらは主にO(1)に非常に大きな定数を加え、O((log N)-1)に小さな定数を加えたものです。正式には、O(と同じです。 log N)、定数は大きなO表記法では重要ではないためですが、実際には重要です。
ハッシュインデックスルックアップの速度低下の多くは、ルックアップと同時にハッシュテーブルのサイズ変更が原因で発生する破損やデッドロックから保護する必要があるためです。最近のバージョン(言及するすべてのバージョンがコミカルに古くなっている)までは、この必要性により、定数がさらに高くなり、並行性がかなり低下しました。ハッシュ並行性よりもBTree並行性の最適化に費やされた作業時間が非常に多くなりました。
ハッシュルックアップは、理論的には、キーハッシュがターゲットレコードの物理的な場所に直接マップされる場合のO(1)
操作です。 Postgresでの動作方法は、私が正しく理解していれば、もう少し複雑です。キーハッシュは、OIDを含むbucketにマッピングされます探しています。バケットは複数のページで構成される可能性があり、特定のキー(ハッシュ)が見つかるまで順次スキャンする必要があります。これが、予想よりも遅く見える理由です。
ハッシュインデックスアクセスメソッド ソースコードリポジトリのREADMEファイル にすべての詳細があります。