2009-06-17 2 views
4

パーティションテーブルのインデックス付きカラムでフィルタリングするクエリを実行すると、フルテーブルスキャンが実行される状況があります。postgresql 8.3.7でパーティションテーブルのインデックスを使用するには

明らかに、これはpostgresqlの既知の問題です。詳細はhereで説明しています。

各パーティションでクエリを実行してから、すべての結果に対してUNIONを実行する以外に、より洗練された方法がありますか?

+0

また、Postgresのパフォーマンスメーリングリストhttp://archives.postgresql.org/pgsql-performance/で質問してください。 –

+0

あなたがリンクしているその記事は、著者がパーティション化に精通していないため不正確です。 彼はconstraint_exclusionまたは各パーティションに対してインデックスを有効にしませんでした。 –

+0

クエリがパーティションの境界を横断するだけでインデックスを除外する理由を理解できません。私の場合は、各パーティションにインデックスを持つ列の非常に小さな値セットを見つけるときにこの問題を発見しました。パーティション上の別の列を選択するとインデックススキャンが使用されます。親テーブルの同じものが各パーティションの全テーブルスキャンを行い、その後マージして並べ替えます。 "select union select union select ..."から別の列を選択するのは "親から別の列を選択する"よりも速くなります。なぜ誰かがプランナーが明白なことをしない理由を知りませんか? – ideasculptor

答えて

10

インデックスは、PostgreSQLの関連するパーティションだけをスキャンするのに問題ありません。しかし、それを正しく機能させるためには、すべてを正しく設定しなければならず、文書化された長いリストの一歩を逃すのは簡単です。http://www.postgresql.org/docs/current/static/ddl-partitioning.html

主なことは、順次スキャンを避けるためには、 PostgreSQLに十分な情報を提供しなければならないので、探しているデータを持つパーティションがいくつかあることを証明できます。クエリ結果の潜在的なソースとしてスキップされます。リンク先の記事では、seqスキャンの問題の解決策としてこれを指摘しています。「各パーティションの日付フィールドに範囲制約を追加すると、このクエリは、「最新の」パーティションを最初にクエリし、残りのすべてのパーティションの範囲よりも高い単一の値が見つかるまで後方に移動します。 " - しかし、変更後の改善されたプランは表示されません。

いくつかの一般的なミスあなたが作ったかもしれない:

postgresql.confファイル内-The constraint_exclusionのパラメータは、デフォルトではオフになっています。そのデフォルトでは、あなたは期待したことを得ることができません。

- CHECKを使用して重複しないパーティションを作成しないでください。これにより、プランナーはそれぞれの内部に何が入っているかを知ることができません。このステップを逃すことは可能ですが、適切なパーティションにデータを正しく取り込むことができます。プランナーはそれを知ることができません。

- 各パーティションにインデックスを付けないでください。マスターテーブルに作成されたインデックスのみです。これは関連するパーティションだけで逐次スキャンを実行するので、上記と同じくらい悪いわけではありません。

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

関連する問題