5

パーティション分割されたテーブルのインデックス付きの列でフィルター処理するクエリを実行すると、テーブル全体のスキャンが実行される状況があります。

どうやら、これは postgresql の既知の問題であり、ここで詳しく説明されています。

各パーティションでクエリを実行し、すべての結果で UNION を実行する以外に、これを回避するよりエレガントな方法はありますか?

4

1 に答える 1

11

インデックスは、PostgreSQL 内の関連するパーティションのみをスキャンするために問題なく機能します。しかし、それが機能するにはすべてを適切に設定する必要があり、http://www.postgresql.org/docs/current/static/ddl-partitioning.htmlで文書化されている長いリストのステップを見逃すのは簡単です。

認識すべき主なことは、シーケンシャル スキャンを回避するために、PostgreSQL に十分な情報を提供して、探しているデータが一部のパーティションにないことを証明できるようにする必要があるということです。その後、それらはクエリ結果の潜在的なソースとしてスキップされます。リンク先の記事は、これを seq スキャンの問題の解決策として指摘しています。残りのすべてのパーティションの範囲よりも高い単一の値が見つかるまで後方に移動します。" -- しかし、その変更後に見られる改善された計画は示されていません。

あなたが犯したかもしれないいくつかの一般的な間違い:

-postgresql.conf ファイルの constraint_exclusion パラメータはデフォルトでオフになっています。そのデフォルトでは、期待どおりの結果が得られません。

-CHECK を使用して重複しないパーティションを作成しませんでした。これにより、プランナーは各パーティションの内容を知ることができなくなります。このステップを見逃す可能性がありますが、それでもデータを適切なパーティションに適切に入れることができます。プランナーはそれを知りません。

-各パーティションにインデックスを配置せず、マスター テーブルに 1 つだけ作成しました。これにより、関連するパーティションのみが順次スキャンされるため、上記ほど悪くはありませんが、良くもありません。

今後の PostgreSQL リリースでこれをすべて簡単にするための作業があります (constraint_partition の設定は 8.4 ではかなり自動化されており、ある種のパーティション設定の自動化が行われています)。今のところ、指示に注意深く従い、これらの問題をすべて回避すれば、うまくいくはずです。

于 2009-06-21T16:28:27.607 に答える