web-dev-qa-db-ja.com

postgresqlの複数の列に対する複数のインデックスと単一のインデックス

このトピックに関する既存の投稿のいくつかを読んで、私は決定的な答えに到達できませんでした。

過去10年間、100か所に特定のデータがあります。テーブルには約8億の行があります。主に、各場所の年間統計を生成する必要があります。時々、月次変動統計と時間変動統計も生成する必要があります。 2つのインデックスを生成する必要があるかどうか疑問に思います-1つは場所用、もう1つは年用、または1つのインデックスを場所と年の両方に生成します。私の主キーは現在、シリアル番号です(おそらく、場所とタイムスタンプを主キーとして使用できます)。

ありがとう。

17

リレーションで作成したインデックスの数に関係なく、特定のクエリで使用されるのはそのうちの1つだけです(クエリ、統計などに依存します)。したがって、あなたの場合、2つの単一列のインデックスを作成しても累積的なメリットは得られません。インデックスからほとんどのパフォーマンスを得るには、(場所、タイムスタンプ)で複合インデックスを使用することをお勧めします。

... WHERE timestamp BETWEEN smth AND smthのようなクエリは上記のインデックスを使用しませんが、... WHERE location = 'smth'または... WHERE location = 'smth' AND timestamp BETWEEN smth AND smthのようなクエリは使用することに注意してください。これは、インデックスの最初の属性が検索と並べ替えに不可欠であるためです。

実行することを忘れないでください

ANALYZE;

統計を収集するためのインデックス作成後。

pdate: As @ MondKinコメントに記載されているように、特定のクエリは実際に同じリレーションで複数のインデックスを使用できます。たとえば、a = 123 OR b = 456のようなOR句を使用してクエリを実行します(両方の列にインデックスがあると仮定)。この場合、postgresは両方のインデックスに対してビットマップインデックススキャンを実行し、結果のビットマップのユニオンを構築し、それをビットマップヒープスキャンに使用します。特定の条件では、同じスキームをANDクエリに使用できますが、ユニオンの代わりに交差があります。

18
Ildar Musin

このような状況の目安はありません。本番DBのコピーを実験して、1つのマルチカラムインデックスまたは2つのシングルカラムインデックスが最適であるかを確認することをお勧めします。

Postgresの優れた機能の1つは、複数のインデックスを作成し、それらを同じクエリで使用できることです。チェック ドキュメントのこの章

... PostgreSQLには、複数のインデックスを組み合わせて、単一のインデックススキャンでは実装できないケースを処理する機能があります...

...複数列のインデックスが最適な場合もありますが、個別のインデックスを作成し、インデックスの組み合わせ機能に依存する方がよい場合もあります...

個別のインデックスと組み合わせたインデックスの両方を作成し、 各インデックスの大きさ を確認して、それらを同時に持つ価値があるかどうかを確認することもできます。

実験できること:

  • テーブルが大きすぎる場合は、 パーティション分割 を検討してください。場所または日付でパーティション化できるようです。パーティション化により、テーブルのデータが小さなテーブルに分割され、クエリが検索する必要のある場所の数が減ります。
  • データが日付(トランザクション日付など)に従って配置されている場合は、 BRINインデックス を確認します。
  • 複数のクエリが同じ方法でデータを処理する場合(同じ期間のすべてのトランザクションを集計する場合など)は、 マテリアライズドビュー を確認してください。これらのコストのかかる集計を1回だけ実行する必要があります。

複数列のインデックスを配置する順序については、最初に等値演算を実行する列を配置し、その後に>=または<=演算を実行する列を配置します。

5
MondKin

(location、timestamp)のインデックスは、2つの別々のインデックスよりもうまく機能するはずです。列の順序が重要であることに注意してください。

1
redneb