52章プランナが統計情報をどのように使用するか本章は、項13.1と項13.2で扱われている題材を基にしていて、問い合わせの各段階において返される行数を推定するために、プランナがシステムの統計情報をどのように使用するかを説明します。これは、計画作成および最適化処理の重要な部分で、コスト計算用の多くの生材料を提供します。本章の目的は、コードを文書化することではありません。このためにはコード自体を参照した方がよいでしょう。どのように動作するのかに関する概要を表すことが目的です。これによりおそらく、後にコードを参照するユーザの習得速度が向上するでしょう。成り行き上、じょじょに複雑化する例を並べて解析するという手法を選びました。以下で示す出力とアルゴリズムは、バージョン8.0のものを使用しています。以前(あるいは以降の)のバージョンとは動作が変わっているかもしれません。使用している例は、リグレッションテスト用データベースから抜き出したものです。非常に簡単な問い合わせから始めましょう。width=244)プランナがどのようにtenk1の濃度を決定するかについては項13.1で説明しました。ここで完全になるように繰り返し説明します。行数はpg_classから検索されます。10000プランナはrelpages推定値を検査し(これは安価な操作です)、正しくなければ、行推定を得るためにreltuplesを測定します。この場合は以下のように正しくありませんでした。10000次にWHERE句に範囲条件を持つ例に進みましょう。1000)プランナは、WHERE句条件を検査します。1000そして、<演算子用の制限関数をpg_operatorから検索します。これはoprrest列に保持されており、今回の場合、検索結果はscalarltselとなります。このscalarltsel関数は、pg_statisticsからunique1用の度数分布を取り出します。以下のように、これは、より単純化したpg_statsビューを使用して行うことができます。1000"で占められる度数分布率を取り出します。この度数分布は、範囲を等頻度のバケットに分割します。行わなければならないことは、値が入るバケットを見つけ、その部分と、その前にあるバケット全体を数えることだけです。1943)にあります。従って、値が各バケットの中で線形に分布していると仮定すると、選択度を以下のように計算することができます。0.1031つまり、1つのバケット全体に、2番目のバケットとの線形比率を加えたものを、バケット数で割ったものとなります。ここで、行の推定値は、選択度とtenk1の濃度を掛け合わせたものとして計算されます。1031次に、WHERE句に等価条件を持つ例を検討してみましょう。'ATAAAA'::name)繰り返しますが、プランナはWHERE句の条件を検査します。'ATAAAA'そして、=演算子用の制限関数をから検索します。結果はeqselとなります。今回の場合は少し異なり、もっとも一般的な値、MCVが選択度を決定するために使用されます。他の列も参照しながらこれらを見てみましょう。ここで参照した列は後で使用します。'ATAAAA'に対応する、最も一般的な頻度(MCF)となります。0.003推定される行数は単に前回同様、この値とtenk1の積です。30この後に行われる推定検査のため、EXPLAINで出力される値はこれより多少大きくなっています。ここで、同じ問い合わせを見てみます。今回は定数がMCV内にありません。'xxx'::name)値がMCVの一覧にない場合、選択度をどのように推定するかは大きく異なります。値が一覧にない場合に使用される方法は、MCVすべての頻度に関する知識を組み合わせたものです。0.001465つまり、全てのMCVの頻度を足し合わせ、MCVの中にはありませんので、その結果を1から差し引き、そして、残りの個別値数で割ります。NULL値が含まれていないので、NULL値を考慮する必要がない点に注意してください。行数の推定値はこれまで通りに計算されます。15複雑さを増して、WHERE句に複数の条件を持つ場合を検討しましょう。'xxx'::name))独立であることが仮定され、個々の制限の選択度が掛け合わせられます。0.00015104行数の推定値はこれまで通りに計算されます。2最後に、WHERE句で互いへのJOINを持つ問い合わせを見てみましょう。50"に関する制限が、入れ子状ループ結合の前に評価されます。これは、前の範囲に関する例と同様に扱われます。前例と同様、<用の制限演算子はscalarlteqselです。度数分布の最初のバケットにありますので、以下のようになります。51結合用の制限は以下の通りです。t1.unique2これは、tenk1を外側のループとする、入れ子状ループ結合方法が使用されているためです。演算子は、よく知られた、単なる=ですが、制限関数はpg_operatorのoprjoin列から取り出されます。この制限関数はeqjoinselとなります。以下のように、tenk2とtenk1の両方の統計情報を使用します。|今回の場合、すべての値が一意であるため、unique2に関するMCV情報がありません。両リレーションの個別値数とNULL値の部分のみに依存したアルゴリズムを使用することができます。0.0001これは、各リレーションにおいて、1からNULL部分を差し引き、個別値数の小さい方の値で割った値です。この結合が生成するはずの行数は、入れ子状ループ内の2つのノードのデカルト積の濃度に、この選択度を掛けたものとして計算されます。51詳細に興味を持った方向けに、リレーション内の行数の推定はsrc/backend/optimizer/util/plancat.cで説明されています。句の選択度に関する計算ロジックについてはsrc/backend/optimizer/path/clausesel.cにあります。演算子と結合に関する制限関数の実際の実装についてはsrc/backend/utils/adt/selfuncs.c内にあります。