列デモグラフィックの導出 - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLリクエストおよびトランザクション処理

Product
Advanced SQL Engine
Teradata Database
Release Number
17.05
17.00
Published
2020年6月
Language
日本語
Last Update
2021-03-30
dita:mapPath
ja-JP/ykx1561500561173.ditamap
dita:ditavalPath
ja-JP/ykx1561500561173.ditaval
dita:id
B035-1142
Product Category
Software
Teradata Vantage

最適化ルーチンは、いくつかの異なる方法で派生統計を取得します。次のトピックでは、統計を導出するための一般的な収集方法について説明しています。

単一テーブル スパース結合インデックスを使用した列デモグラフィックの導出

リレーションの単一テーブル述部を完全に、またはその一部をカバーする単一テーブル スパース結合インデックスがある場合、最適化ルーチンはそのインデックスを使用して残余列のデモグラフィックを導出します。このメカニズムにより、単一テーブル結合インデックスを使用して、列の相関を自動的に導出することができます。

例えば、次の結合インデックスが定義されているとします。

CREATE JOIN INDEX ji AS
 SELECT c1, d1
 FROM t1
 WHERE x1 > 10
 AND   y1 =10;

次のクエリーを実行依頼します。

SELECT t1.c1, COUNT (*)
FROM t1, t2
WHERE t1.d1 = t2.d2
AND   t1.x1 > 10
AND   t1.y1 = 10
GROUP BY 1;

jiで統計を使用する際に、システムは、単一テーブル述部t1.x1 > 10およびt1.y1 = 10の適用後に、列t1.c1とt1.d1のデモグラフィックを導出できます。 新しく導出されたデモグラフィックを、結合列t1.d1の結合計画と集約見積もりで使用して、グループ化列t1.c1のグループの数を決定できます。

また、部分カバー結合インデックスを、すべての適用可能なケースでデモグラフィックの導出に使用できることに注意してください。例えば、次の結合インデックスを定義するとします。

CREATE JOIN INDEX ji AS
  SELECT c1, d1
  FROM t1
  WHERE x1 > 10;

次のクエリーを実行依頼します。

SELECT t1.c1, COUNT (*)
FROM t1, t2
WHERE t1.d1 = t2.d2
AND   t1.x1 > 10
AND   t1.y1 = 10
GROUP BY 1;

この場合、部分カバー結合インデックスからのデモグラフィック情報は、列c1とd1で使用されます。デモグラフィック情報を基本テーブルと結合インデックスの両方から入手できる場合、結合インデックス情報は一部の単一テーブル述部に関する相関関係情報も取得するので、より高い優先順位が与えられます。

集約結合インデックスを使用した列デモグラフィックの導出

最適化ルーチンは、集約結合インデックスから、グループ化列の固有値を導出できます。派生値は結合計画に使用できます。これは、自動的に、および単一テーブル述部適用後に、グループ化列セット内の列相関情報を導出するための別の方法です。

例えば、次の集約結合インデックスが定義されているとします。

CREATE JOIN INDEX ji AS
  SELECT a1, SUM (b1)
  FROM t1
  WHERE x1 > 10
  AND y1 = 10
  GROUP BY c1, d1;

次のクエリーを実行依頼します。

SELECT *
FROM t1, t2
WHERE t1.c1 = t2.c2
AND   t1.d1 = t2.d2
AND   x1 > 10
AND   y1 = 10;

集約結合インデックスのカーディナリティは、列(t1.c1、t2.d1)の固有値の個数です。これらの列の固有値が既に基本テーブル統計から入手可能な場合、システムは集約結合インデックスからの情報でその固有値を更新するか、新しい派生統計エントリを生成します。固有値は、統合計画で結合カーディナリティと値ごとの行数の見積もり、スキュー検出などを行なう際に使用できます。

部分カバー集約結合インデックスは、非集約単一テーブル スパース結合インデックスと同じ方法で処理され、集約結合インデックスが派生テーブルまたはビューに取って代わる場合、そのインデックスからの統計が自動的に使用されることに注意してください。

CHECK制約と参照整合性制約を使用した列デモグラフィックの導出

統計がない場合、CHECKおよび参照整合性制約も最適化ルーチンに有効な情報を提供します。例えば、2つの値MおよびFのみを持つことができる、patient_sexと呼ばれる列について考えてみます。一般に、ユーザーは、patient_sex IN ("M","F")のようなデータベースCHECK制約で、この列の整合性を強化します。

この列に統計がなく、問合わせが述部 patient_sex = 'M'を指定する場合、システムでは、通常、等価条件のデフォルトにより行の10%が適格であると仮定されます。ただし、この列は2つの値しか持つことができないので、より合理的なデフォルト値は50%です。


適格な行の総数の式

最適化ルーチンは、開いた範囲または閉じた範囲のようなCHECK制約、または統計が利用できない場合はINリストを考慮します。開いた範囲は、問合わせ述部が範囲を閉じることができるシナリオに役立ちます。例えば、CHECK制約が開いた範囲x1 > 10を指定し、問合わせが述部x1 < 20を指定する場合、その組合わせによって閉じた範囲が生成されます。これは、列のデモグラフィックを導出する際に使用できます。

同様に、プライマリ キーと外部キーの関係において子テーブル上に統計がなく、親テーブルのPK列に統計が存在する場合、固有値の個数のような親テーブルPK列のデモグラフィックの多くを、子テーブル内のFK列に導出および使用できます。この情報は、単一テーブルの見積もり、および結合カーディナリティと値ごとの行数の見積もりについての結合計画で使用できます。統計の収集に法外に費用がかかる場合、このような種類の見積もりは大きな子テーブルに使用すると有効です。

このメカニズムは、非強制の参照制約の参照整合性制約(ソフトの参照整合性制約としても知られている)とともに使用すると効果的です。これは、統計を収集せずに、最適化ルーチンに子テーブルのデモグラフィック情報を提供します。

このメカニズムでは、子テーブルに親テーブルのすべての値があることを前提としています。値のサブセットのみがある場合、またはこの結合列内の値セットに大きなひずみがある場合は、子列上で統計を収集して、ひずみがある再分散とカーディナリティの過小見積もりを避ける必要があります。

派生統計のフレームワークは、この種の情報を、問合わせ最適化の事前結合計画段階でCHECKおよび参照制約から収集し、そこから結合計画段階に伝搬します。

単一テーブル述部を使用した列デモグラフィックの導出

単一テーブルの見積もりロジックは、あらゆる述部について、適切な行数とともに、適切な固有値の数と頻度度数を決定します。最適化ルーチンは、単一テーブル述部で指定される列が結合と集約のような後続の演算にも指定される場合に、この情報を使用することができます。

システムは、次の方法でこの情報を得ることができます。
  • 基本テーブル統計の使用
  • 単一テーブル結合インデックスでの統計の使用

基本テーブル統計を使用することにより、Vantageは単一テーブル述部を述部で指定されている列で使用して、列のデモグラフィックを導出できます。ただし、導出した情報を、他の単一テーブル述部に基づいて後から調整することはできません。これは、列の相関情報がない場合、列は独立しているという仮定に基づいています。

例えば、次の問合わせがあるとします。

SELECT *
FROM t1, t2
WHERE   t1.d1 = t2.d2
AND     t1.d1 BETWEEN '1999-01-01' AND '2000-01-01'
AND     t1.c1 > 10;

基本テーブル統計を使用して、固有値の適切な個数と高い最頻度数が、列t1.d1の派生統計エントリで導出および格納されます。

一方で、利用可能な単一テーブル結合インデックスを使うことにより、最適化ルーチンはすべての単一テーブル述部を適用後、列のデモグラフィックを入手できます。

例えば、前述の問合わせをサポートするため、次の結合インデックスが定義されていると仮定します。

CREATE JOIN INDEX ji AS
  SELECT t1.d1
  FROM t1
  WHERE   t1.d1 BETWEEN '1999-01-01' AND '2000-01-01'
  AND     t1.c1 > 10;

間隔ヒストグラムが結合インデックス列t1.d1で利用可能な場合、それには高い優先順位が指定され、派生統計で取得されます。これは、両方の単一テーブル述部が適用された後、間隔ヒストグラムは列t1.d1のデモグラフィックを反映するためです。最適化ルーチンで単一テーブル結合インデックス統計を使用して、基本テーブル列を参照する複合式のカーディナリティを見積もる方法については、結合インデックス統計を使用した単一テーブルの式のカーディナリティの見積もりを参照してください。

派生情報は、結合カーディナリティの見積もり、値ごとの行数の見積もり、および_スキュー検出などの結合計画段階で再利用されます。

一般に、最適化ルーチンは、複雑な述部を除き、問合わせ計画のカーディナリティの見積もりに使用できる述部を考慮します。下のテーブルは、最適化ルーチンが考慮する述部の例と、それらの述部のカーディナリティの見積もりに使用する統計を示しています。

述部 定義
IS NULL 自己定義
自己定義
IS NOT NULL
  • nullが存在する場合、値は(TotalValues - 1)として計算されます。
  • nullが存在しない場合、値はTotalValuesになります。
TotalRows - Nullの数
単一の等価条件 自己定義
  • 間隔に孤立値/最頻値がある場合、値はその度数になります。
  • 間隔に孤立値/最頻値がない場合、値は次のように計算されます:
すべての列における等価条件付きのインデックス 自己定義
自己定義
NE TotalValues - 1
この値のHighModeFreqを除く、分布のHighModeFreq
  • LT
  • LE
  • GT
  • GE
適切な間隔から導出された値数
適切な間隔のHighModeFreq
BETWEEN LowValues + HighValues - TotalValues
適格な範囲間隔のHighModeFreq
  • OR演算用語
  • INリスト
OR演算リスト内の要素数
すべてのOR演算要素の最大度数
NOT IN用語 TotalValues - NOT INリスト内の要素数
すべてのINリスト要素を除いたあとのHighMode

考慮されない条件タイプの例として、x1=10 OR y1>20のような、複数列を参照するOR演算があります。

統計がない場合の単一テーブル述部を使用した列デモグラフィックの導出

EQ、INリスト、OR演算述部、または閉じた範囲のような単一テーブル述部が問合わせで指定される場合、Vantageは固有値数などの一部の情報を導出できます。その情報は、列統計が利用できない場合に、結合計画で後から使用することができます。

例えば、次のクエリーでは、このような統計が導出されます。

SELECT *
FROM t1, t2
WHERE t1.d1 = t2.d2
AND   t1.d1 in (10, 20);

この列で統計が収集されていなくても、派生統計は、特定の単一テーブル述部に基づいて、固有値の個数情報を取得して、結合プランナーに伝搬します。

単一テーブル述部と複数列(PARTITION)統計を使用した列デモグラフィックの導出

単一テーブル述部を結合リクエストに適用した後、結合列のデモグラフィックが必要です。最適化ルーチンは複数列統計を使用して、一部の単一テーブル述部を使用する結合列のデモグラフィックを導出できます。これは、複数列統計を使用して列相関を自動的に導出する別の方法です。

例えば、次の問合わせを実行依頼するとします。

SELECT *
FROM t1, t2
WHERE t1.d1 = t2.d2
AND   t1.x1 > 10;

結合プランナーは、単一テーブル述部t1.x1>10適用後に、結合列t1.d1のデモグラフィックを認識する必要があります。t1に複数列統計(x1, d1)がある場合、派生統計によってt1.d1のデモグラフィックが導出されます。PPIテーブルでは、行パーティション排除があり、複数列PARTITION統計が利用可能な場合、結合列のデモグラフィックは、適切なパーティションに基づいて導出されます。

複数列統計内の列の順番がこれらの見積もりにとって重要であることに注意してください。複数列統計の収集について指定した順番に関係なく、列は、昇順フィールドIDに基づいて内部的に並べ替えられます。このため、列d1のフィールドIDが列x1より小さい場合、複数列統計は内部的に(d1, x1)として順序付けられます。この場合、x1の所定の述部に、d1のデモグラフィックを導出することはできません。複数列PARTITION統計では、PARTITION列が常に最初の列であることに注意してください。これは、PARTITION列に常に内部フィールドIDの0があるためです。

最適化ルーチンが列の相関を導出する際に考慮する単一テーブル述部には、等価条件(x1=10)、INリスト(x1 IN (10, 20, 30))、同じ列上の単純なOR演算リスト(x1=10 OR x1=20)、および範囲述部(x1 BETWEEN 10 AND 30, x1>10)などがあります。

最適化ルーチンで単一テーブル結合インデックス統計を使用して、基本テーブル列を参照する複合式のカーディナリティを見積もる方法については、結合インデックス統計を使用した単一テーブルの式のカーディナリティの見積もりも参照してください。

非正規化スキーマで単一列と複数列統計を使用して階層関係を検出

派生統計のフレームワークは、統計を使用して、非正規化テーブルの階層関係を検出します。関係は派生統計に値のマッピングとして保存されます。デモグラフィックを調整する際に使用される唯一のマッピングは、1 -->  nのリレーションシップがあるマッピングです。

単一および複数列統計の組合わせは、これらの関係を検出するのに必要です。

単一列への変更は、階層チェーン全体を通じてカスケードします。例えば、x --> yについての値のマッピングが1 --> 5であり、y-->  zについての値のマッピングが1 --> 10である場合、1つの値がxから削除されると、5つの値がyから削除され、10の値がzから削除されます。

具体的に言うと、region --> nationの間のリレーションシップが、1 -->  5であることが検出され、1つの地域が選択されている場合、最適化ルーチンは5つの国のみが対象であることを検出します。

つまり、単一テーブル述部によって1つの地域が無効にされると、最適化ルーチンはnation列から5つの国を削除します。

次の例では、このロジックについて説明しています。次のように定義されている非正規化ディメンション テーブルのcustomer_nation_regionについて考えてみます。

CREATE SET TABLE cust_nation_region (
  c_custkey       INTEGER,
  c_name          VARCHAR(25) CHARACTER SET LATIN CASESPECIFIC,
  c_address       VARCHAR(40) CHARACTER SET LATIN CASESPECIFIC,
  c_nationkey     INTEGER,
  c_phone         CHAR(15) CHARACTER SET LATIN CASESPECIFIC,
  c_acctbal       DECIMAL(15,2),
  c_mktsegment    CHAR(10) CHARACTER SET LATIN CASESPECIFIC,
  c_comment       VARCHAR(117) CHARACTER SET LATIN CASESPECIFIC,
  c_maritalstatus CHAR(1) CHARACTER SET LATIN NOT CASESPECIFIC,
  n_name          CHAR(25) CHARACTER SET LATIN CASESPECIFIC,
  n_comment       VARCHAR(152) CHARACTER SET LATIN CASESPECIFIC,
  r_regionkey     INTEGER,
  r_name          CHAR(25) CHARACTER SET LATIN CASESPECIFIC,
  r_comment       VARCHAR(152) CHARACTER SET LATIN CASESPECIFIC)
  PRIMARY INDEX (c_custkey);
この例では、関係は単一行および複数列統計の組み合わせから導出されます。関係を検出する際には、次の統計が必要です。
  • r_regionkeyの単一列
  • r_regionkeyの単一列
  • r_regionkeyの単一列
  • (r_regionkey, n_nationkey)の複数列
  • (n_nationkey, c_custkey)の複数列
次の関係が検出されます。
  • region -->  nationは1 --> 5
  • nation -->  customerは1 -->  24,000
次のクエリーでは、1つのregionkey値のみを選択する述部を指定しています。このクエリーで、前述の例とそのEXPLAINテキストを確認できます。
EXPLAIN SELECT n_nationkey
FROM cust_nation_region
WHERE r_regionkey = 1
GROUP BY 1;
EXPLAIN出力の一部を次に示します。
...
 2) Next, we lock TPCD_OCES3.cust_nation_region for read.3) We do an all-AMPs SUM         step to aggregate from TPCD_OCES3.cust_nation_region by way of an all-rows
        scan with a condition of ("TPCD_OCES3.cust_nation_region.R_REGIONKEY = 1"),
        grouping by field1 ( TPCD_OCES3.cust_nation_region.N_NATIONKEY).
        Aggregate Intermediate Results are computed globally, then placed
        in Spool 3.  The size of Spool 3 is estimated with low confidence 
        to be 5 rows  (525 bytes). The estimated time for this step is
        0.62 seconds.
     -> The total estimated time is 0.63 seconds.

regionおよびnation間の既知の階層リレーションシップである1 -->  5から、nationkey行の予想数は5となります。これは、EXPLAINテキストの中で太字で示されています。一般には、2つのregionkey値を選択するリクエストを書き込んだ場合、結果セットには10のnationkey行が存在することになります。

部分集合と上位集合統計を使用した列デモグラフィックの導出

複数の結合述部があり、結合列に一定程度の相関がある場合、複数列統計は結合カーディナリティ、値ごとの行数、スキューの検出、および関連統計をより正確に見積もる際に必要です。複数列統計がなく、列が独立していると仮定される場合、最適化ルーチンは固有値の個別の数を乗算して、固有値の合計数を見積もります。ただし、結合列の上位集合である複数列統計が存在する場合、列が独立していると仮定される場合よりも、列の相関に関して有効な情報を取得できる場合があります。

例えば、次の問合わせについて考えてみます。

SELECT *
FROM t1, t2
WHERE t1.d1 = t2.d2
AND   t1.x1 = t2.x2;

システムでカーディナリティとコストを正確に見積もるには、(t1.d1, t1.x1)と(t2.d2, t2.x2)に複数列統計が必要です。t1.d1に100の固有値があり、t1.x1に50の固有値がある個別統計がある場合、列が独立しているものと仮定すると、固有値は乗算され、その最大合計数が計算されて(100 * 50 = 5,000)、行の総数に上限が設定されます。

派生統計サブシステムは、事前結合段階でそのような機会を特定し、上位集合に基づいてダミー複数列統計を導出します。例えば、(x1, y1, d1)のような、2,000の固有値のみを含む上位集合の複数列の統計情報収集が存在する場合、最適化ルーチンは、2,000の固有値がある派生統計エントリ(x1, y1)を導出することによって、見積もり固有値のカーディナリティ5,000をより正確な2,000に制限し、その統計を結合計画に伝搬します。

同様に、(x1)、(d1)および(x1, d1)のような個別のエントリと複数列統計エントリがあり、x1 IN (1,2) AND d1 < 20のような単一テーブル述部がある場合、最適化ルーチンは、単一テーブルの見積もりを作成しながら、単一列エントリのデモグラフィックを更新できます。単一列エントリから更新された情報に基づいて、派生統計の複数列エントリが更新および伝搬されます。

結合述部を使用した列デモグラフィックの導出

最適化ルーチンは、結合のカーディナリティとコストを見積もる際に、結合に均一性があるものと仮定します。つまり、結合内の左側のリレーション内の値の数が右側のリレーション内の右側の値の数より少ない場合、左側のリレーションのすべての値が右側のリレーションと一致すると仮定します(逆の場合も同様)。

この仮定では、結合述部がt1.d1 = t2.d2である場合、t1.d1に100の固有値があり、t2.d2に50の固有値があると、結合後、t1.d1は50の固有値だけを保有します。 最適化ルーチンは、複数列の統計も考慮して調整を行ないます。 例えば、次の述部と100の固有値がある(x1, y1)および50の固有値がある(x2, y2)がある場合、結合後、(x1, y1)の固有値の数は50に調整されます。

t1.x1=t2.x2 AND t1.y1=t2.y2

派生統計サブシステムはこの種の分析を実行し、各バイナリ結合後に、固有値の個数や頻度度数のような結合列のデモグラフィックを調整し、調整したデモグラフィック情報を結合計画プロセスの次の段階に伝搬します。

列の相関情報が入手可能な場合、最適化ルーチンはそれを使用して、結合列での調整に基づいて、その他の列のデモグラフィックを調整します。それ以外の場合、結合列は他の列から独立していると仮定されます。

t1.d1には100、t2.d2には50、t3.d3には200の固有値があるとします。

次の問合わせを実行依頼するとします。
SELECT t3.d3, COUNT (*)
FROM t1, t2, t3
WHERE t1.d1 = t2.d2
AND   t1.d1 = t3.d3
GROUP BY 1;

最初の結合後の結合順序が(t1 x t2) x t3と仮定すると、派生した統計サブシステムは固有の値t1.d1を固有の値の最小数(t1.d1, t2.d2) = 50に調整します。

2番目の結合後、派生統計サブシステムはt3.d3の固有値の数を50に調整します。この数は、最後の集約見積もりに使用されます。これは、t3.d3がグループ化列として指定されるからです。

各バイナリ結合後の結合述部冗長性を使用した列デモグラフィックの導出

一部の結合述部は、システムが1つ以上のバイナリ結合を実行した後、冗長になる場合があります。問合わせの選択性という面に何の影響も与えない場合、その述部は冗長です。これは、述部の効果が、その問合わせで指定される他のの述部と同等であるためです。

冗長性は、推移的閉包またはユーザー定義問合わせ条件のいずれかが原因で発生します。そのような冗長述部が、カーディナリティの見積もりおよびコスト計算中に正しく特定または処理されない場合、それらは問合わせの最適化に悪影響を及ぼす可能性があり、最適でない問合わせ計画が作成される恐れがあります。

例えば、次の問合わせを実行依頼するとします。

SELECT *
FROM t1, t2, t3
WHERE t1.d1 = t2.d2
AND   t1.d1 = t3.d3;

推移閉包は、このリクエストに、新しい述部t2.d2 = t3.d3を導出します。結合順序が(t1 x t2 -->   j1) x t3であるとすると、2番目の結合の結合述部はj1.d1 = t3.d3およびj1.d2 = t3.d3になります。

推移閉包の詳細については、述部簡略化を参照してください。

結合j1について、(d1,d2)の固有値の個数を見積もる際に、最適化ルーチンは、これらの2つの列がすでに前の結合で一致されていることを確認し、これら個別の固有値を乗算してその合計数が計算されないようにする必要があります。代わりに、固有値の合計数としてMIN(j1.d1, j1.d2)を使用する必要があります。

派生統計インフラストラクチャは、各バイナリの結合後に、すべての接続された結合列をEquiSetsにまとめることにより、適切なエントリを構築します。このように後続の結合によって、冗長性がシームレスに処理されます。

結合計画では、EquiSetは、同じ問合わせの前回の結合演算の述部で、等しいと定義された列のセットです。問合わせで再利用するために、EquiSetを後続の結合演算に伝搬することは、派生統計のフレームワークの基礎的な構成要素です。

例えば、前の例では、EquiSet派生統計エントリの(j1.d1, j1.d2)は、j1結合後に、d1とd2の値の最少個数で存在します。後続の結合が組み合わせ(j1.d1, j1.d2)の固有値をリクエストする場合、最適化ルーチンは自動的に既存のEquiSetエントリを使用します。

複数の情報源の処理による列デモグラフィックの導出

前のトピックで説明したように、固有値の個数や頻度度数のような情報は、単一表結合インデックス、複数列統計、動的AMPサンプル、および間隔ヒストグラムなど複数の情報源から取得および導出されます。

利用可能なソースのどれが最も有効で信頼できるかを判断することは簡単なことではありません。次の基準すべてが、判断を行なう上で重要なロールを果たします。
  • 情報源は一番高い相関を取得する。
  • 情報源は単一テーブル述部の最大数をカバーする。
  • 情報源は利用可能な情報の最も新しい(つまり、最も古くない)ソースである。

例えば、複数の単一テーブル述部をカバーする非相関デモグラフィック情報を生成する結合インデックスを持つことが可能である一方で、結合列の相関の情報を生成する1つの単一テーブル述部をカバーする複数列統計が存在する場合があります。

このような問題から、経験則に基づいた優先順位ルールを定義することはできません。この制限に対処するため、最適化ルーチンは情報を定量化して、導出量に基づいて述部を動的に定義します。
  • 最初の2つの基準、単一テーブル

    これは最少の固有値を提供する情報源の使用に変換されます。

    述部の最高の相関性と最大数は、固有値の個数を使って定量化できます。
  • 3番目の基準である最も古くない統計も、古い統計情報で検討および説明されています。

すべての一時的なコミット済み結合への列デモグラフィックの伝搬

列デモグラフィックは派生統計フレームワークを使用して、すべての一時的なコミット済み結合に伝搬されます。結果として、デモグラフィックは各結合後に動的に調整できるので、結合プランナーは基本テーブル間隔ヒストグラムを参照して、統計を取得する必要はありません。

問合わせブロック内の具体化されたインスタンスへの列デモグラフィックの伝搬

複雑な述部または外部結合を問合わせで指定する場合、最適化ルーチンが問合わせブロック内で結合計画を実行している間、それらはスプール リレーションに具体化される場合があります。

複雑なON句述部を含む次の外部結合クエリーを実行依頼するとします。

SELECT *
FROM t1 INNER JOIN t2 ON (x1=x2)
        LEFT OUTER JOIN t3 ON (x2 NOT IN (SELECT x4
                                          FROM t4)
                                      OR y3=10);

この問合わせのON句述部のx2 NOT IN (SELECT x4 FROM t4) OR y3=10によって、この複合外部結合が作成されます(Subquery がON句で指定される場合、述部は半複合または複合に分類されます)。

複雑な外部結合を処理するための要件の1つに、左側のリレーションが1つのみであるという点があります。この左側のリレーション(t1, t2)は、システムが複雑な結合を処理する前に、単一のスプール リレーションに具体化されます。左側のリレーションの具体化後、派生統計は、具体化されたインスタンスの射影された列デモグラフィック情報を、結合計画の後続の段階に伝搬します。

集約および順序付き分析関数見積もりへの列デモグラフィックの伝搬

一連の結合後に集約および順序付き分析カーディナリティ見積もりを実行できるようにするには、最終集約が実行されるまでに、結合演算全体にグループ化列のデモグラフィック情報を伝搬する必要があります。派生統計サブシステムは、単一テーブルおよび結合述部に基づいてデモグラフィック情報を調整し、最終集約が完了するまでそれを先へ伝搬します。例えば、次の問合わせを実行依頼するとします。

SELECT t1.x1, t2.x2, COUNT (*)
FROM t1, t2
WHERE t1.x1 =10
AND   t1.y2 = t2.x2
GROUP BY 1, 2;

事前結合計画段階では、派生統計は列x1 (t1.x1=10)で単一テーブル等価条件を検出し、固有値の数を1に調整します。結合計画を実行している間、t2.x2の固有値の個数は、(t1.y2, t2.x2)の値の最少個数に調整されます。これで、集約カーディナリティ見積もりが改良されます。このため、このクエリー ブロックがスプールされている派生テーブルまたはビューである場合は、計画全体を改良することができます。

問合わせブロック全体にわたる列デモグラフィックの伝搬

次の問合わせを実行依頼するとします。

SELECT *
FROM t1, (SELECT x2, x3, COUNT(*)
          FROM t2, t3
          WHERE x2=10
          AND   t2.x3=t3.x3
          GROUP BY 1, 2) AS dt
WHERE t1.x1=dt.x3;

派生統計のフレームワークは、派生テーブル述部に基づいて調整を行ない、派生テーブルdtの列x2とx3の列デモグラフィック情報を伝えます。調整済みデモグラフィックは、外部ブロックの結合計画に伝搬されます。

ヒストグラムを使用したカーディナリティの見積もり

カーディナリティ見積もりにヒストグラムを使用できる式には、単項演算子または2項演算子のいずれかを含めることができます。オペランドの1つは、列、組み込み関数、または次のリストのいずれかのSQL演算子にする必要があります。
  • UPPER
  • LOWER
  • NULLIFZERO
  • ZEROIFNULL
  • SUBSTR
  • MOD
  • 同じテーブルの列のCONCAT
  • 列の暗黙的または明示的データ型変換
サポートされている演算子は次のとおりです。
  • =
  • >
  • <
  • <>
  • IS NULL
  • IS NOT NULL
  • LIKE
  • NOT LIKE
  • BETWEEN
  • IN
2項演算子では、一方のオペランドを次のいずれかを含む単純式にすることができます。
  • 構文解析プログラムで値を計算できる定数。
  • システムのUSINGリクエスト修飾子データ、またはCURRENT_DATE値のような組み込み関数データ。
  • 同じテーブルの別の列を含む単純表現式。

    例えば、単一テーブル述部t1.x1 = t1.y1の選択性は、デフォルトの選択性公式を使用するのではなく、2つの列の重複する値を検討することによって、より合理的に見積もることができます。

LIKE述部の選択性を見積もる場合は、"abc%"パターンかつ保守的な見積もり公式のみの使用に限定されます。

次の文がすべて真である場合、最適化ルーチンは述部のグループに複数列ヒストグラムを使用できます。
  • 述部が、複数列ヒストグラムの最初のnフィールドに指定されている。

    このルールは、複数列ヒストグラムのフィールドに、順序付けの依存関係があるために存在します。

  • 述部は、複数列ヒストグラムの最初のフィールドを除いて、等価条件を指定する必要があります。
  • 複数列の最初の列の述部が非等価条件の場合、最適化ルーチンは、この述部にのみ複数列ヒストグラムを使用します。

例えば、(x, y, z)のヒストグラムは、述部x>100およびx=10 AND y=20の選択性を見積もる際に使用できます。

最適化ルーチンでは、日付の外挿によって導出された日付を使用することによって、日付関連の述部のカーディナリティをより正確に見積もることができます(古い統計を置き換えるための外挿の使用を参照)。

選択性の結合

最適化ルーチンは個々の列を検出し、その組み合わせされた選択性を、個々の選択性の積として計算します。個々の列の2つのカテゴリは、次のように定義されます。
  • 1列のすべての値が、その他の列のすべての値にマップする。

    この場合、組み合わせされる値の数は、個々の列の値の数の積です。customerテーブルの列nationと列market-segmentを例として取り上げます。

    各国は、すべてのマーケット セグメントのビジネスに参加し、各マーケット セグメント内のビジネスはすべての国で提供されます。

  • 1列の値は、その他の列の値によって制限されない。ただし、2つの独立した列の最初の列の値が指定されると、最初の列の値が2番目の列のすべての値に均等に配分される。

    customerテーブルの列market-segmentと列account-balanceは、このような独立した列の例です。一方、1つのアカウント残高、すなわち$100.23がすべてのマーケット セグメント内に存在しない場合でも、アカウント残高は特定のマーケット セグメントに限定されません。

最適化ルーチンが列の独立性を検出できないケースとして、次の3つがあります。
  • すべての列の総サイズが、ヒストグラム データの行サイズ制限の16バイトを超える場合。この場合、複数列ヒストグラムには、列の独立性について正確な判断をするための情報が揃っていないため、独立性に関するテストは失敗する可能性があります。
  • 独立性の検出機能は、個々の選択性に対する信頼度が高い場合のみ有効になります。つまり、列で統計が収集されていないこと、または式が複雑であることが原因で、述部の選択性の信頼度が低い場合、最適化ルーチンは列の独立性を検出しようとしません。
  • 独立性の検出機能は、個々の列における述部の選択性見積もりが基本テーブル ヒストグラムに基づいている場合のみ有効になります。

結合列またはグループ化列のセット内の固有値数の検出

結合カーディナリティ見積もり、値ごとの行数の見積もり、スキュー検出、集約見積もり、部分的Group By見積もり、およびいくつかのその他の計算すべてにおいて、結合列またはグループ化列の所定のセットについての固有値の個数を見積もる必要があります。

最適化ルーチンは、統計の可能な組み合わせすべてにおいて徹底的な検索を実行し、重複のない最良の統計セットを決定します。決定されたセットは、次に、最適化プロセスのすべての段階で、固有値の個数、頻度度数、AMP度数値を検出する際に使用されます。

このアルゴリズムの主要な目的は次のとおりです。
  • 最少個数の固有値を持つ、重複しない組合わせの統計のセットを検出する。

    完全なカバー範囲が検出できない場合、最大数の列をカバーし、最少個数の固有値がある、重複しない組合わせの統計のセットを検出する。

  • すべての列をカバーすることにより、頻度度数とAMP度数の最高の値を提供する、重複のない組合わせの統計のセットを検出する。

最少個数の固有値を提供する組合わせのセットは、高い頻度度数と高いAMP度数値の最適な見積もり値を提供するセットと同じでない場合があります。これは、高い頻度度数と高いAMP度数は、基本テーブル間隔ヒストグラム以外のソースから導出されるエントリの一部には利用できない場合があるからです。

統計がすべてのハッシュ列または結合列をカバーしない場合、部分統計から決定される固有値の個数は、値ごとの行数および結合カーディナリティの見積もりで考慮されます。これは、この手法が保守的なものであるためです。ただし、最適化ルーチンは非常に積極的にコスト見積もりを作成するので、この見積もりをスキュー調整および部分的GROUP BYで考慮しません。その結果、コスト計算の見積もりが大きく間違っている場合、計算時に過度に積極的な方法が取られるため、パフォーマンスに問題が発生する可能性があります。つまり、所定のハッシュ列または結合列が統計で完全にカバーされない場合、最適化ルーチンは部分的GROUP BY計画を回避し、スキュー調整を実行しません。

固有値検出アルゴリズムは次の情報を提供します(カーディナリティ見積もりのためのさまざまな最適化ルーチンの信頼度レベルの定義についてはEXPLAINの信頼度レベルを参照)。
  • MinValsとその信頼度レベル

    この見積もりは、所定の列の集合に、絶対最少個数の値を提供します。最大数の列をカバーする単一派生統計エントリから値が取得されます。同じ数の列をカバーする複数のエントリがある場合、最適化ルーチンは、最高個数の値があるエントリを選択します。

    次のテーブルでは、さまざまなエントリの信頼度レベルを説明しています。

    利用可能な派生統計エントリ 信頼度レベル
    検出される場合 高い信頼度
    検出されない場合 信頼度なし
  • BestValsとその信頼度レベル
    これは、次の両方の基準を満たす派生統計エントリのセットから導出できる、最適数の値の見積もりを提供します。
    • 最多数の列をカバーする
    • 最少数の値を生成する

    所定の列集合の同じセットまたは部分集合である派生統計エントリが、これらの値の生成時に使用されます。

    場合によっては、値は、一部の列のみをカバーする派生統計エントリのセットからも取得できます。例えば、すべての列をカバーするのに十分な統計がある場合などです。

    次のテーブルでは、さまざまなエントリの信頼度レベルを説明しています。

    派生統計エントリの状況 信頼度レベル
    単一のエントリがすべての列をカバーする 高い信頼度
    次の任意のである場合
    • すべての列をカバーするために、複数のエントリを組み合わせる必要がある
    • 列の部分集合のみがカバーされる
    低い信頼度
    利用可能な派生統計エントリが検出されない 信頼度なし
  • MaxValsとその信頼度レベル

    この見積もりは、所定の列の集合に、最多数の可能値を提供します。部分集合、上位集合、EquiSet、または重複するエントリいずれかである派生統計エントリは、これらの値の生成時にすべて考慮されます。

    すべての列がこれらのエントリによってカバーされない場合、次のテーブルで説明されているように、デフォルトの見積もりがドメイン タイプに基づいて、カバーされない列に使用されます。

    派生統計エントリの状況 信頼度レベル
    単一のエントリがすべての列をカバーする 高い信頼度
    すべての列をカバーするために、複数のエントリを組み合わせる必要がある 低い信頼度
    デフォルトの見積もりが値の計算時に使用される 信頼度なし

MinValsが、高いまたは低いレベルの信頼度で検出される場合、最適化ルーチンは常にBestVals統計を求めることができます。ただし、信頼度が高い、または低いMaxValsを求めることも可能ですが、BestValsまたはMinValsを求めることはできません。

最適化ルーチンは、信頼度が高い場合または低い場合に、その結合カーディナリティとRowsPerValue見積もりにBestValsを使用します。

部分的GROUP BY、集約、およびスキュー検出では、常にMaxValsが使用されます。

値は、確率論的モデルを使用して、次の2つのレベルで組み合わせされます。

  1. 同じソースからの値は組み合わせされます。

    組み合わせした値の数は、ソースの総行数までに制限されます。

  2. 異なるソースから組み合わせした値は、最終値を得るために自身を組み合わせします。

    これらは現在のセットの総行数に基づいて制限されます。

複数列統計がEquiSetと重複する場合、システムはEquiSetエントリを利用してから、追加の結合を導出します。例えば、所定のハッシュ列(x1, x2, y2)に利用可能なエントリがEquiSet [x1, x2]および(x2, y2)]の場合、最適化ルーチンは、複数列統計エントリ(x2, y2)をその他のEquiSet列とともに増やし、新しいエントリ(x1, x2, y2)を動的に生成します。

次の例では、さまざまな可能性について説明しています。

最初の例では、次の派生統計エントリについて考えてみます。

列セット 固有値の数
(a1, b1) 10
(b1, c1) 15
(a1, b1, c1) 20

ハッシュ列が(a1, b1, c1)の場合、次の値と信頼度レベルが最適化ルーチンによって導出されます。

統計 信頼度レベル
MinVals 20 高い信頼度
BestVals 20 高い信頼度
MaxVals 20 高い信頼度

2番目の例では、次の派生統計エントリについて考えてみます。

列セット 固有値の数
(a1, b1) 10
(c1) 5

ハッシュ列が(a1, b1, c1, d1)の場合、次の値と信頼度レベルが最適化ルーチンによって導出されます。

統計 信頼度レベル
MinVals 10 高い信頼度
BestVals 50

列セットの固有値の個数の積から計算されます。 10×5 = 50

低い信頼度
MaxVals 50とd1のデモグラフィック見積もりの組み合わせ 信頼度なし

最後の例では、次の派生統計エントリについて考えてみます。

列セット 固有値の数
(a1, b1, c1, d1) 100

ハッシュ列が(a1, b1, c1)の場合、次の値と信頼度レベルが最適化ルーチンによって導出されます。

統計 信頼度レベル
MinVals TotalRows 信頼度なし
BestVals TotalRows 信頼度なし
MaxVals 100 低い信頼度