プランナ/オプティマイザの役割は最適な実行計画を作ることです。 ある与えられたSQL問い合わせは(それがある問い合わせツリーになるのですが)、同じ結果をもたらす、多くの異なった方法で実際には実行できます。 もしもコンピュータの演算として可能であれば、問い合わせオプティマイザは可能な実行プランを全て検証し、実行するとした場合に一番早く結果をもたらすと想定される実行計画を選択します。
注意: 場合によっては問い合わせをどう実行するかの選択を検証するために、膨大な時間とメモリ空間を消費する可能性があります。 特に規模の大きな結合操作に問い合わせが関わった時などです。 ほどよい時間内でほどよい(最適ではありません)問い合わせ計画を決定するためにPostgreSQLは遺伝的問い合わせ最適化を使用します。
このプランナの検索手順は、実際には経路という名前のデータ構造を使用します。 経路とは、プランナが決定を行うために必要な情報のみに切り詰めた単なる計画の表現です。 最も安価である経路が決定された後、全てが揃った計画ツリーが作成されてエクゼキュータに渡されます。 これはつまり、要求されている実行計画はエクゼキュータがそれを実行するために十分な詳しい内容を所有していることを表しています。 本節の残りでは、経路と計画の違いについて無視します。
プランナ/オプティマイザは、問い合わせの中で使用される個々のリレーション(テーブル)をスキャンするための計画を生成することから始めます。 各リレーション上で利用できるインデックスにより実行可能な計画が決まります。 リレーションをシーケンシャルスキャンする可能性は常にありますので、シーケンシャルスキャンを使用する計画は常に作成されます。 リレーション上にインデックス(例えばB-treeインデックス)が定義され、問い合わせにはrelation.attribute OPR constantという条件があるとしましょう。 もしrelation.attributeがB-treeインデックスのキーと一致し、OPRがインデックスの 演算子クラスに列挙されている演算子の1つであれば、リレーションをスキャンするためにB-treeインデックスを使用する別の計画が作られます。 さらに他のインデックスが存在し、問い合わせの中で条件がインデックスのキーに一致した場合、なおその上に計画が検討されます。
単一のリレーションをスキャンする可能性がある全ての計画が見つかると、リレーションを結合するための計画が作られます。 プランナ/オプティマイザはWHERE条件の中で一致する結合句が存在する全ての2つのリレーション(例えばそれに対してwhere rel1.attr1=rel2.attr2のような条件が存在する場合)を選択して考慮します。 結合句のない結合の組み合わせは他に選択の余地がない場合のみ考慮されます。 つまり、ある特定のリレーションは他のいかなるリレーションに対して有効な結合句を所有しない場合です。 プランナ/オプティマイザに考慮された結合の組には全ての実行可能な計画が作られます。 3つの実行可能な結合戦略です。
入れ子反復結合: 左側のリレーションの中で見つけられた行ごとに右側のリレーションが1回スキャンされます。 この戦略は実装が簡単ですが、時間がかかる場合があります (とは言っても右側のリレーションがインデックススキャンによってスキャン可能であればよい戦略になります。 右側のインデックススキャンのキーとして左側のリレーションの現在の行の値を使用することができます)。
マージソート結合: 結合を開始する前に、それぞれのリレーションを結合属性でソートします。 そして、2つのリレーションを並行してスキャンし、一致する行を結合行の形にまとめます。 それぞれのリレーションがたった1回しかスキャンされなくて済むのでこの結合は魅力的です。 要求されるソートは、明示的なソート段階、または、結合キー上のインデックスを使用して適切な順序でリレーションをスキャンすることにより行われます。
ハッシュ結合: 右側のリレーションがハッシュキーとして結合属性を用いて初めにスキャンされ、ハッシュテーブルに読み込まれます。 次に左側のリレーションがスキャンされ、見つかったそれぞれの行に相応しい値が、右側のリレーションの行を探し出すためのハッシュキーとして使われます。
問い合わせが3つ以上のリレーションを含む場合、それぞれ2つの入力を持つ結合段階のツリーによって最終結果を構築しなければなりません。 プランナは最も低コストな計画を見つけ出すために、あり得る異なった結合順序を検証します。
最終的な計画ツリーは基になっているリレーションのシーケンシャルもしくはインデックススキャン、そして必要に応じて入れ子ループ、マージ、またはハッシュ結合のノード、さらにはソートまたは集約関数計算ノードのような必要とされる補助の手順から構成されます。 これらほとんどの計画ノード型は選択(特定の理論演算条件に合致しない行を破棄すること)および射影(与えられた列の値に基づき派生した列の集合を計算すること、つまり必要なところでスカラ式の評価をすること)を行う追加的能力を持っています。 プランナの1つの責任は、WHERE句から選択条件を付加して計画ツリーの最も適切なノードに対し必要とされる出力式を計算することです。