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

The task of the planner/optimizer is to create an optimal execution plan. It first combines all possible ways of scanning and joining the relations that appear in a query. All the created paths lead to the same result and it's the task of the optimizer to estimate the cost of executing each path and find out which one is the cheapest.

プランナ/オプティマイザの機能は最適な実行プランを作成することです。 始めに、問合せの中に出てくるリレーションに対して、可能性のある全ての スキャンと join を結合します。オプティマイザがやることは同一の結果を 導く全てのパスに対して、それぞれのパスを実行する上での経済効果を推定し、 最も効率の良いパスを見つけ出すことです。

可能性のあるプランの生成

The planner/optimizer decides which plans should be generated based upon the types of indices defined on the relations appearing in a query. There is always the possibility of performing a sequential scan on a relation, so a plan using only sequential scans is always created. Assume an index is defined on a relation (for example a B-tree index) and a query contains the restriction relation.attribute OPR constant. If relation.attribute happens to match the key of the B-tree index and OPR is anything but '<>' another plan is created using the B-tree index to scan the relation. If there are further indices present and the restrictions in the query happen to match a key of an index further plans will be considered.

プランナ/オプティマイザは問合せに出現するリレーションに対して定義される インデックスのタイプに基づいてどのプランが生成されるべきか判断します。 リレーションに対して逐次スキャンを行う可能性は常にあるため、 逐次スキャンは必ず生成されます。(たとえば B-tree インデックスのように) リレーションに対してインデックスが定義され、問合せに relation.attribute OPR constant 制限が含まれて いるとします。もし relation.attribute が B-tree インデックスのキーに一致し、OPR が単に '<>' の場合は、 リレーションをスキャンする B-tree インデックスを使用して他のプラン が作成されます。更にいくつかのインデックスが存在し、あるインデックス のキーと問い合わせの中の条件が一致した場合は更なるプランが検討 されます。

After all feasible plans have been found for scanning single relations, plans for joining relations are created. The planner/optimizer considers only joins between every two relations for which there exists a corresponding join clause (i.e. for which a restriction like where rel1.attr1=rel2.attr2 exists) in the where qualification. All possible plans are generated for every join pair considered by the planner/optimizer. The three possible join strategies are:

単一のリレーションをスキャンする全ての実行可能プランが検出された後、 リレーションを join するプランが作成されます。プランナ/オプティマイザ は、対応する where 制限事項の中の join 句が存在する、 (すなわち where rel1.attr1=rel2.attr2 が存在するような制限) 二つ毎のリレーション間の join のみを検証します。 プランがプランナ/オプティマイザによって検討された全ての可能性のある プランがそれぞれの join の組合せに対して生成されます。 可能性のある join の戦略として三種類あげられます。

プランのデータ構造

Here we will give a little description of the nodes appearing in the plan. Figure \ref{plan} shows the plan produced for the query in example \ref{simple_select}.

ここでプランに現れるノードについて簡単に記述します。図 \ref{plan} は 例 \ref{simple_select} の問合せに対して作成されたプランを示しています。

The top node of the plan is a MergeJoin node which has two successors, one attached to the field lefttree and the second attached to the field righttree. Each of the subnodes represents one relation of the join. As mentioned above a merge sort join requires each relation to be sorted. That's why we find a Sort node in each subplan. The additional qualification given in the query (s.sno > 2) is pushed down as far as possible and is attached to the qpqual field of the leaf SeqScan node of the corresponding subplan.

プランの最上ノードは、lefttree に付くものと righttree に付くものの、二つの継承を持った MergeJoin ノードです。それぞれのサブノードは、その join の一つのリレーションを表します。上述したように、マージ・ソート join ではそれぞれのリレーションがソートされていることが必要です。 従って、それぞれのサブプランに Sort ノードが あるわけです。問合せ(s.sno > 2)において与え られた追加の制限事項は可能な限り下位に押し下げられ、対応するサブプラン の SeqScan リーフノードの qpqual フィールドに付けられます。

The list attached to the field mergeclauses of the MergeJoin node contains information about the join attributes. The values 65000 and 65001 for the varno fields in the VAR nodes appearing in the mergeclauses list (and also in the targetlist) mean that not the tuples of the current node should be considered but the tuples of the next "deeper" nodes (i.e. the top nodes of the subplans) should be used instead.

MergeJoin ノードの mergeclauses に 付けられたリストは join 属性についての情報を含んでいます。mergeclauses リスト(および targetlist も同様)の中に出現する VAR ノードの varno フィールドに対する値、 6500065001 は現在のノードのタプルが検証されるのではなく、次に深い ノード(すなわちサブノードの最上ノード)のタプルが替わりとして検証されることを意味 しています。

Note that every Sort and SeqScan node appearing in figure \ref{plan} has got a targetlist but because there was not enough space only the one for the MergeJoin node could be drawn.

図 \ref{plan} に出てくる全ての SortSeqScan ノードは targetlist を既に取得していますが、充分なスペースが充分でないため MergeJoin ノードに対する一つだけが描かれています。

Another task performed by the planner/optimizer is fixing the operator ids in the Expr and Oper nodes. As mentioned earlier, Postgres supports a variety of different data types and even user defined types can be used. To be able to maintain the huge amount of functions and operators it is necessary to store them in a system table. Each function and operator gets a unique operator id. According to the types of the attributes used within the qualifications etc., the appropriate operator ids have to be used.

プランナ/オプティマイザによってもたらされる他の機能として ExprOper ノードの中の 演算子 id を 修正することがあります。前に述べたように、Postgres は 各種異なったデータ型をサポートするとともにユーザが定義する型も使用可能です。 巨大な量の関数と演算子の保守を可能とするためそれらをシステムテーブルに保存しておく 必要があります。それぞれの関数や演算子は一意な演算子 id が与えられます。 条件などの中で使用される属性の型に従って、適切な演算子 id が使用されなければ なりません。