範囲タイプの正確な等価性に起因する不適切なクエリプランの処理方法
tstzrange変数の正確な等価性が必要な更新を実行しています。〜1M行が変更され、クエリには〜13分かかります。の結果はここでEXPLAIN ANALYZE見ることができ、実際の結果はクエリプランナーが推定した結果とは大きく異なります。問題は、インデックススキャンで単一の行が返されることを期待していることです。t_range これは、範囲タイプの統計が他のタイプの統計とは異なる方法で保存されるという事実に関連しているようです。pg_stats列のビューを見ると、n_distinctis -1であり、他のフィールド(most_common_valsなどmost_common_freqs)は空です。 ただし、t_rangeどこかに統計が保存されている必要があります。完全に同等ではなくt_rangeで「within」を使用する非常に類似した更新の実行には約4分かかり、実質的に異なるクエリプランを使用します(こちらを参照)。一時テーブルのすべての行と履歴テーブルのかなりの部分が使用されるため、2番目のクエリプランは理にかなっています。さらに重要なことは、クエリプランナーがのフィルタに対してほぼ正しい行数を予測することt_rangeです。 の分布t_rangeは少し珍しいです。このテーブルを使用して別のテーブルの履歴状態を保存していますが、他のテーブルへの変更は大きなダンプで一度に発生するため、の値はあまり多くありませんt_range。の一意の値のそれぞれに対応するカウントはt_range次のとおりです。 t_range | count -------------------------------------------------------------------+--------- ["2014-06-12 20:58:21.447478+00","2014-06-27 07:00:00+00") | 994676 ["2014-06-12 20:58:21.447478+00","2014-08-01 01:22:14.621887+00") | 36791 ["2014-06-27 07:00:00+00","2014-08-01 07:00:01+00") | 1000403 ["2014-06-27 07:00:00+00",infinity) | 36791 ["2014-08-01 07:00:01+00",infinity) | 999753 t_range上記のdistinctのカウントは完了しているため、カーディナリティは〜3Mです(このうち〜1Mは、いずれかの更新クエリの影響を受けます)。 クエリ1のパフォーマンスがクエリ2よりもはるかに低いのはなぜですか?私の場合、クエリ2が適切な代替品ですが、正確な範囲の均等性が本当に必要な場合、Postgresでよりスマートなクエリプランを使用するにはどうすればよいですか? インデックス付きのテーブル定義(無関係な列の削除): Column | Type | Modifiers ---------------------+-----------+------------------------------------------------------------------------------ history_id | integer | not null default nextval('gtfs_stop_times_history_history_id_seq'::regclass) …