web-dev-qa-db-ja.com

CLUSTERコマンドの代わりに大きなテーブルのインデックスをカバーするPostgreSQL

大きなテーブルでCLUSTERコマンドを実行して、データをディスク上で効率的に整理する代わりの方法を探しています。クラスター化されているテーブルにACCESS EXCLUSIVEロックが必要であり、かなりの時間使用できなくなるためです。

インデックスをカバーする について読んだ後、btree複数列のインデックスを指定してクエリ条件に関連するものだけでなく、テーブル列のすべて

メリットは2つあると思います。

  1. クエリの予想されるデータフェッチパターンに従って、インデックスで最初に条件関連の列が指定されるため、クエリプランが最適化されます。
  2. 残りのすべての列もインデックスに含まれます。つまり、このインデックスはテーブルのコピーであり、btree構造により、ディスク上ですでに効率的に編成されています。 。

このインデックスに対するクエリは非常に効率的であり、テーブル全体をカバーしているため、ディスク上に散在するテーブルデータにアクセスする必要はないと思います。

これが合理的な解決策であるかどうか、そしてこのアプローチの潜在的な欠点は何であるかを尋ねたいですか? (カバーするインデックスに必要な追加のストレージスペースに加えて、予想される-小さい?-挿入/更新/削除のパフォーマンスの低下)

PostgreSQLにはカバーインデックスがありません。それらについてはいくつかの作業が行われていますが、コードツリーにはまだ受け入れられていません。

したがって、制限があります。インデックス付きの列の一部のプレフィックスに一意の制約がある場合、それをサポートするために別のインデックスが必要になります。大きなインデックスに便乗することはできません。また、一部のデータ型はBtree演算子をサポートしていません。つまり、btreeインデックスに含めることができません。たとえば、XMLまたは多くの幾何学的タイプ。

また、インデックス付きの値はページの3分の1、つまり約2700バイトを超えることはできないため、インデックスに幅の広い列を含めると、この理由で失敗する可能性があります(インデックスが存在する場合、それをカバーしてもこの問題は解決しないと思います) )

最後に、「すべて表示」とマークされたテーブルページについてテーブルを参照することは避けてください。テーブルがほとんど静的である場合、おそらく問題ではありません。ただし、テーブルが非常に動的である場合、「すべての可視」カウントを維持するには、非常に積極的なバキュームが必要になります。

テーブルを分割することは別のオプションかもしれません。クラスタリングほどきめ細かくはありませんが、継続的な負担を軽減できます。特に、すべてのアクティブな更新が1つまたは2つのパーティションに対して行われ、残りは事実上読み取り専用である場合。

3
jjanes