17.00 - 17.05 - 行パーティション排除 - Advanced SQL Engine - Teradata Database

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

Product
Advanced SQL Engine
Teradata Database
Release Number
17.00
17.05
Published
2020年6月
Content Type
プログラミング リファレンス
ユーザー ガイド
Publication ID
B035-1142-170K-JPN
Language
日本語 (日本)

行パーティション排除について

行パーティション排除は、行パーティション テーブルまたは結合インデックスの問合わせ結果セットを返すためにスキャンする必要のある行パーティション数を制限するメソッド群です。問合わせの検索条件を満たす行を含まない行パーティションをスキップことで、パーティション排除を実行します。行パーティション排除は、自動的に行なわれる最適化です。最適化ルーチンは、問合わせ条件およびパーティション式に基づいて、そのパーティション式の一部の行パーティションに、条件に適合する行が含まれるかどうかを判断します。行が含まれない行パーティションは、ファイル スキャン中にスキップすることができます。特定の問合わせでスキップされる行パーティションは、排除済み行パーティションと呼ばれます。

Vantageは、次のようなタイプの行パーティション排除をサポートしています。
  • 静的
  • 遅延
  • 動的

Vantageでは、列パーティション化されたテーブルや結合インデックスに対するさまざまな形式の列パーティション排除もサポートしています。列パーティション排除の詳細については、列パーティション排除を参照してください。

リクエスト内の行パーティション排除メソッドの混在

行パーティション排除のメソッドは、同じクエリーの中で混在させることができ、また、テーブルまたは結合インデックスに列と行両方のパーティションがある場合、列パーティション排除のメソッドと混在させることもできます。例えば、静的行パーティション排除は一部のパーティション レベルに使用できます。一方、動的行パーティション排除はその他のレベルに使用することができます。また、一部のレベルでは、行パーティション排除も必要ない場合があります。一部のパーティション レベルでは、複数の形式のパーティション排除を組み合わせることによって、さらにスキャンを簡略化することができます。

複数の行パーティション式がある場合、Vantageは、スキャンが必要なデータ部分集合の数をさらに減らすために、各レベルでの行パーティション排除を組み合わせます。ほとんどの場合、行パーティション化の最大の利点は、パーティション排除から得られます。

Vantageは、複数のレベルの検索条件、またはそれを組み合わせることにより、パーティションを排除できます。

行パーティション排除があると、完全シリンダ読み取りの最適化はサポートされなくなります。このため、パーティション化について検討する際には、その代償についても考える必要があります。最適化ルーチンは、可能な限り行パーティション排除を使用します。ただし、最適化ルーチンは、ブロック読み取りを使用して行パーティションのサブセットを読み取るコストについて、完全シリンダ読み取りを実行するフル テーブル スキャンのコストを見積もりません。ほとんどの場合、行パーティション排除には、完全シリンダ読み取りを実行するフル テーブル スキャンより大きな利点があると考えることができます。

静的行パーティション排除

クエリー最適化の初期の段階で、最適化ルーチンによる行パーティション排除の指定をクエリー条件が許可する場合、使用される行パーティション排除の形式を静的行パーティション排除と呼びます。

パーティション列の単一テーブル制約は、静的行パーティション排除に使用できます。この制約には、システム派生PARTITION列や、システム派生PARTITION#Ln列セットの任意ののメンバーにおける単一テーブル制約が含まれます。ここでは、nの値の範囲は1から62以内になります。

このパーティション排除方法の詳細については、 静的行パーティション排除を参照してください。

遅延行パーティション排除

問合わせ条件が、USINGリクエスト修飾子変数から、または組み込み関数の結果から一部導出された比較に基づいている場合、最適化ルーチンは、その他の場合と同様に、キャッシュされている問合わせ計画を再使用できません。これは、キャッシュされている計画には、この後の実行において検索条件値の変化を処理するのに十分な汎用性が必要だからです。

この場合、最適化ルーチンは、最適化プロセスの後の時点で、特定計画の実行用の値を使用してキャッシュされている計画から最終的な問合わせ計画を構築するときに、行パーティション排除を適用します。この形式のパーティション排除は、遅延行パーティション排除と呼ばれます。

この行パーティション排除方法の詳細については、遅延行パーティション排除を参照してください。

動的行パーティション排除

他のテーブルの値を参照する問合わせ条件が、リクエストが実行されるときに行パーティション排除の実施を許可する場合、その行パーティション排除は動的と呼ばれます。

行パーティション排除を問合わせ実行時に許可する問合わせ条件が、その他のテーブル内の値を参照する場合、問合わせが最適化されたあと、および問合わせの実行中に、AMPデータベース ソフトウェアによって行パーティション排除が動的に実行されます。この形式のパーティション排除は、動的行パーティション排除と呼ばれます。

Vantageは、範囲条件付き動的行パーティション排除と呼ばれる特殊な形式の動的行パーティション排除を使用できます。このパーティション排除は、特定の左テーブル パーティションと右テーブルの行パーティの連続する範囲を結合するときに、その行パーティションの範囲が範囲結合条件から導き出せる場合に使用されます。この形式の動的行パーティション排除は、RANGE_Nパーティション化を使用する単一レベルでパーティション化されたテーブルに対してのみサポートされます。

動的行パーティション排除を使用して、結合を単純化し、そのパフォーマンスを強化することができます。このとき、行パーティション排除に使用するように設計されている結合方法のセットから、最もコストが低い方法が選択されます。

このパーティション排除方法の詳細については、 動的行パーティション排除による積結合を参照してください。

文字パーティションの排除

文字パーティションの排除は行パーティション排除と区別されるものではありませんが、いくつか固有の特徴があります。

文字パーティションは、通常、非文字行パーティション化と比べて少ない数のパーティションを定義します。パーティションCHECK制約には16,000文字という制限があるので、文字パーティションの実効制限は約2,000パーティションです(パーティションCHECK制約とその各種形式の詳細について、<Teradata Vantage™ - データベースの設計、B035-1094>または<Teradata Vantage™ - SQLデータ定義言語 - 詳細トピック、B035-1184>の「CREATE TABLE」を参照)。結果として、非常に大きなテーブルに対して文字パーティションを指定する場合、通常はマルチレベル パーティション式の一部として指定するのが最も効果的です。

定義可能な組み合わせパーティションの最大数までの文字パーティション化されたテーブルの場合、複数のパーティション レベルでパーティション排除を組み合わせてから、1/2000というおおよその制限から読み取る必要のある組み合わせパーティションの比率を減少させることができます。

例えば、次のテーブルは、65,475のパーティションを定義します。内部パーティション番号を2バイトと仮定すると、このパーティション数は2バイトのパーティション化に定義できる組み合わせパーティションの最大数65,535に近い数です。この場合、27の行パーティションがレベル1に定義され、485の行パーティションがレベル2に、5つの行パーティションがレベル3に定義されます。

CREATE TABLE markets (
  productname     VARCHAR(50) NOT CASESPECIFIC,
  region          BYTEINT NOT NULL,
  activity_date   DATE FORMAT 'yyyy-mm-dd' NOT NULL,
  revenue_code    BYTEINT NOT NULL,
  business_sector BYTEINT NOT NULL,
  note            VARCHAR(256))
PRIMARY INDEX (productname, region)
PARTITION BY (RANGE_N(productname BETWEEN  'A','B','C','D','E','F',
                                           'G','H','I','J','K','L',
                                           'M','N','O','P','Q','R',
                                           'S','T','U','V','W','X',
                                           'Y','Z' AND
              'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ',
              NO RANGE OR UNKNOWN),
              RANGE_N(activity_date BETWEEN DATE '1998-10-01'
                                    AND     DATE '2007-12-31'
                                    EACH INTERVAL '7' DAY,
              NO RANGE, UNKNOWN),
              RANGE_N(revenue_code  BETWEEN 1
                                    AND     4
                                    EACH 1,
              NO RANGE OR UNKNOWN ));

組み合わせパーティションに均等に行を分散すると仮定すると、次のSELECTリクエストは1つの組み合わせパーティションにのみアクセスします。または、markets内の行の1/65,475です。

SELECT *
FROM markets
WHERE productname BETWEEN 'a' AND 'az'
                  AND     activity_date=DATE '2007-08-15'
                  AND     revenue_code=1;

Vantageでは、文字パーティション レベルで行パーティション排除を使用し、さらに他のパーティション レベルでのパーティション排除を併用して、文字パーティション化されたテーブルのみを使用する場合よりもアクセスするデータの部分集合を減らすことができます。これは文字パーティション化されたテーブルで定義できる行パーティションの最大数が約2,000に制限されているためです。

BEGINおよびEND期間範囲関数を指定する行パーティション化の静的および遅延行パーティション排除

BEGINおよびEND期間範囲関数を指定する期間式については、静的行パーティション排除および遅延行パーティション排除のみがサポートされます。

DateTime式の行パーティション排除のルールは、BEGINおよびEND期間範囲関数を組み込んだ次の関数に基づくパーティション式と同じ方法で適用されます。
  • BEGINおよびEND期間範囲関数による直接パーティション化。
  • BEGINおよびEND期間範囲関数を使用するCASE_N関数によるパーティション化。
  • BEGINおよびEND期間範囲関数を使用するCASE関数によるパーティション化。
  • BEGINおよびEND期間範囲関数を使用するRANGE_N関数によるパーティション化。

データベースは、アクセスするテーブルがBEGINまたはEND期間範囲関数を基にしてパーティション化を定義されていて、かつユーザーがWHERE句でBEGINまたはEND期間範囲関数の等号制約を指定している場合のみ、単一パーティション スキャンを実行します。

単一パーティション スキャンを実行するためのルールは次のとおりです。

テーブルのパーティション化に使用されている期間範囲関数 WHERE句で等号制約が指定されている関数 データベースの動作
BEGIN BEGIN期間範囲関数 単一パーティションのアクセス。
END期間範囲関数 単一パーティションのアクセスを実行しない。
BEGIN期間範囲関数とEND期間範囲関数の両方 単一パーティションのアクセス。
END BEGIN期間範囲関数 単一パーティションのアクセスを実行しない。
END期間範囲関数 単一パーティションのアクセス。
BEGIN期間範囲関数とEND期間範囲関数の両方 単一パーティションのアクセス。
BEGINおよびEND BEGIN期間範囲関数 単一パーティションのアクセスを実行しない。
END期間範囲関数 単一パーティションのアクセスを実行しない。
BEGIN期間範囲関数とEND期間範囲関数の両方 単一パーティションのアクセス。

これらのルールを示す例として次のテーブル定義を想定できます。

CREATE SET TABLE t11 (
  a INTEGER,
  b PERIOD(DATE))
PRIMARY INDEX(a)
PARTITION BY CAST((BEGIN(b)) AS INTEGER;

CREATE SET TABLE t12 (
  a INTEGER,
  b PERIOD(DATE))
PRIMARY INDEX(a)
PARTITION BY CAST((END(b)) AS INTEGER);

次の例では、関連するEXPLAINテキスト句を太字で強調表示しています。

次のSELECTリクエストは、WHERE句の述部およびパーティション式が異なる範囲で定義されているので、すべての行パーティションをスキャンします。
EXPLAIN SELECT *
FROM t11
WHERE END(b)=DATE ‘2010-02-03’;
次に、EXPLAIN出力の一部を示します。
...
3) We do an all-AMPs RETRIEVE step from df2.t11 by way of  an 
    all-rows scan  with a condition of  ("(END(df2.t11.b ))= DATE 
    '2010-02-03'")  into Spool 1 (group_amps), which is built locally
   on the AMPs. The size of Spool 1 is estimated with no confidence
   to be 1 row (56 bytes). The estimated time for this step is 0.03
   seconds.

次のSELECTリクエストは、WHERE句の述部がEND期間範囲関数で定義され、パーティション式がEND期間範囲関数上で等号制約を使用して定義されているので、単一パーティション スキャンを実行します。

EXPLAIN SELECT *
        FROM t12
        WHERE END(b)=DATE ‘2011-02-03’;

...
3) We do an all-AMPs RETRIEVE step from  a single partition  of
   df2.t12 with a condition of ("df2.t12.b = PERIOD(DATE '2011-02-03'
    - INTERVAL '1' DAY, DATE   '2011-02-03')")  with a residual condition 
   of ( "(END(df2.t12.b ))= DATE '2011-02-03'")  into Spool 1
   (group_amps), which is built locally on the AMPs. The size of
   Spool 1 is estimated with no confidence to be 1 row (56 bytes).
   The estimated time for this step is 0.03 seconds.
...

次のSELECTリクエストは、WHERE句の述部がEND期間範囲関数で定義され、パーティション式がEND期間範囲関数上で等号制約を使用して定義されているので、単一パーティション スキャンを実行します。

EXPLAIN SELECT *
FROM t12
WHERE a=1
AND   END(b)=DATE ‘2011-02-03’;
...
1) First, we do a single-AMP RETRIEVE step from  a single partition  of
   df2.t12 by way of the primary index "df2.t12.a = 1,
   df2.t12.b = PERIOD (DATE '2011-02-03'- INTERVAL '1' DAY, DATE 
   '2011-02-03')" with a residual condition of ("((END(df2.t12.b ))= 
   DATE '2011-02-03') AND (df2.t12.a = 1)") into Spool 1 (one-amp),
   which is built locally on that AMP. The size of Spool 1 is estimated
   with low confidence to be 1 row (56 bytes). The estimated time for
   this step is 0.02 seconds.

テーブルがBEGINおよびEND期間範囲関数を使用して直接行パーティション化されたために数値になっている場合、およびパーティション式で指定されているパーティション列がリクエスト内の条件に指定されている場合は常に、データベースは、他のDateTime式に適用されるものと同じBEGINおよびEND期間範囲関数のルールを使用して、行パーティション排除を実行します。

次のテーブル定義を想定します。

CREATE SET TABLE t1 (
  a INTEGER
  b PERIOD(DATE)
PRIMARY INDEX(a)
PARTITION BY CAST((END(b) AS INTEGER);

次のSELECTリクエストは、t1の55,333の行パーティションをスキャンします。

EXPLAIN SELECT *
        FROM t1
        WHERE b>PERIOD(DATE ‘1901-02-02);
...
3) We do an all-AMPs RETRIEVE step from  55333 partitions of 
   df2.T1 with a condition of ("df2.T1.b > (PERIOD (DATE '1901-02-02',
   DATE '1901-02-02'))") into Spool 1 (group_amps), which is built 
   locally on the AMPs. The size of Spool 1 is estimated with no
   confidence to be 1 row (56 bytes). The estimated time for this
   step is 0.03 seconds.
...

BEGINまたはEND期間範囲関数を指定するCASE_N関数またはCASE関数を使用してテーブルが行パーティション化される場合、DateTime式を使用した行パーティション排除の既存のルールも適用されます。

次のテーブル定義を想定します。

CREATE TABLE orders (
  o_orderkey      INTEGER NOT NULL,
  o_custkey       INTEGER,
  o_orderperiod   PERIOD (DATE) NOT NULL,
  o_orderpriority CHARACTER (21),
  o_comment       VARCHAR (79))
PRIMARY INDEX(o_orderkey)
PARTITION BY CASE_N(END(o_orderperiod) <= DATE '2010-03-31', /*Q1*/
                    END(o_orderperiod) <= DATE '2010-06-30', /*Q2*/
                    END(o_orderperiod) <= DATE '2010-09-30', /*Q3*/
                    END(o_orderperiod) <= DATE '2010-12-31'  /*Q4*/
                   );

次のSELECTリクエストは、ordersの2つの行パーティションをスキャンし、最初の2四半期に行なわれた発注の詳細を表示します。

EXPLAIN SELECT *
FROM orders
WHERE END(o_orderperiod) > DATE '2010-06-30';
...
3) We do an all-AMPs RETRIEVE step from  2 partitions of 
   df2.orders with a condition of (
   "(END (df2.orders.O_orderperiod))> DATE '2010-06-30'")
   into Spool 1 (group_amps), which is built locally on the AMPs.
   The size of Spool 1 is estimated with no confidence to be 1 row (
   167 bytes). The estimated time for this step is 0.03 seconds.
...

テーブルがBEGINまたはEND期間範囲関数を指定したRANGE_N関数を使用して行パーティション化されている場合、およびパーティション式で指定されている列がリクエスト内の条件に指定されている場合は常に、Teradata Databaseは、DateTime式に適用されるものと同じルールを使用して行パーティション排除を実行します。

次の定義を使用して、sales_historyテーブルを定義するとします。

CREATE TABLE sales_history (
  product_code       CHARACTER(8),
  quantity_sold      INTEGER,
  transaction_period PERIOD(DATE))
PRIMARY INDEX (product_code)
PARTITION BY RANGE_N(END (transaction_period)
                     BETWEEN DATE '2006-01-01'
                     AND     DATE '2015-12-31'
                     EACH INTERVAL'1' YEAR);

次のSELECTリクエストは、2010年より前のsales_historyの5つの行パーティションをスキャンします。

EXPLAIN SELECT *
FROM sales_history
WHERE transaction_period < PERIOD(DATE '2010-01-01');
...
3) We do an all-AMPs RETRIEVE step from  5 partitions of 
   df2.sales_history with a condition of (
   "df2.sales_history.transaction_period < (PERIOD (DATE '2010-01-01',
   DATE '2010-01-01'))") into Spool 1 (group_amps), which is built 
   locally on the AMPs. The size of Spool 1 is estimated with no
   confidence to be 1 row(64 bytes). The estimated time for this step
   is 0.03 seconds.
...

RANGE_Nパーティション式でBEGINまたはEND範囲関数が指定され、問合わせ条件に同じパーティション式が含まれている場合、最適化ルーチンは行パーティション排除を使用します。

次のSELECTリクエストは、sales_historyテーブルの4つの行パーティションをスキャンして、2010年より前のすべての販売履歴を表示します。

EXPLAIN SELECT *
FROM sales_history
WHERE END (transaction_period) < DATE '2010-01-01';
...
3) We do an all-AMPs RETRIEVE step from  4 partitions of 
   df2.sales_history with a condition of (
   "(END(df2.sales_history.transaction_period ))< DATE
   '2010-01-01'") into Spool 1 (group_amps), which is built locally
   on the AMPs. The size of Spool 1 is estimated with no confidence
   to be 1 row (64 bytes). The estimated time for this step is 0.03
   seconds.
...