2.5. プランナ/オプティマイザ

プランナ/オプティマイザの役割は最適な実行計画を 作ることです。 まずはじめに、問い合わせのなかに登場するリレーションをスキャン 結合するための全ての方法をまとめます。つくられた 全てのパスは同じ 結果を得られますが、それぞれのパスのコストを見積もり一番安いものを選ぶの はオプティマイザ の役割です。

2.5.1. 可能な計画を生成する

プランナ/オプティマイザは、問い合わせの中に現れるリレーションで定義され るインデックスの 型に基づいて、どのプランが作られるべきかを決めます。リレーション上で 順スキャンを 行う可能性は常にあるため、順スキャンのみを使ったプランが作られ ます。例えばリレーション上 にインデックス(例えばB-treeインデックス)が定義され、問い合わせは制約 relation.attribute OPR constantを含むとします。もし relation.attributeがB-treeインデックスのキーと同じ でOPR が'<>'以外だった場合、リレーションをスキャンするための 別の計画が B-treeインデックスを使って作られます。もしさらにインデックスがあり問い 合わせの制約が インデックスのキーと同じ場合、さらなる計画が検討されます。

個々のリレーションをスキャンするための全ての可能な計画が見付けられると、 リレーションを結合するための計画が作られます。 プランナ/オプティマイザは、where制約のなかで一致する結合句が存在する 二つの リレーション(例:where rel1.attr1=rel2.attr2の ような制約 が存在する場合)のみを考慮します。プランナ/オプティマイザに考慮 された結合ペアには全ての可能な計画が作られます。 以下は3つの可能な策 です:

2.5.2. 計画のデータ構造

ここでは計画で登場するノードについて簡単に説明します。図\ref{plan}は 例\ref{simple_select} の問い合わせのために作られた計画を表しています。

計画の頂点にあるノードはMergeJoinノードで、二つの 子ノードを持ちます。一つは lefttreeフィールドに付随するもので、二つめは righttree フィールドに付随するものです。それぞれのサブノードは結合の一つの リレーションを表します。 上でもふれたように、マージソート結合は各々のリレーションがあらかじめ ソートされていることを必要とします。 そのために各々のサブプランにSortノードがあるのです。 問い合わせ (s.sno > 2)でさらに与えられる制約は下に押し出 され、相当する サブプランの節SeqScanqpqual フィールドに 付随しています。

MergeJoinノードのmergeclauses フィールドに付随された リストは結合属性に関する情報を持っています。mergeclauses リスト( ターゲットリストにもあります)に現れるVAR ノードにあるverno フィールドの値、6500065001 は現在の ノードのタプルではなく次の「深さ」のノード(つまりサブプランの頂点にある ノード)が使われるべきだということ を意味しています。

図\ref{plan}に現れる全てのSortSeqScan ノードは ターゲットリストを持ちますが、スペースが足りないため MergeJoin ノードのものだけが書かれています。

プランナ/オプティマイザに実行されるもう一つの仕事はExpr Operノードのなかで演算子IDを 調整することです。 はじめのほうで述べたように、Postgres は さまざまなデータ型をサポート し、ユーザ定義のものまで使うことができます。そのような大量の関数や 演算子を保持するためには システムテーブルにそれらを格納しておくことが必要になります。各々の関数 や演算子はユニーク な演算子IDが与えられます。制約のなかで使われる属性の型などに基づいて、 ふさわしい演算子 IDが使わなければなりません。