行パーティション排除は、パーティション列をUSINGリクエスト修飾子変数(ホスト変数を含む)と比較する条件や、CURRENT_DATEまたはCURRENT_TIMESTAMPのような組み込み関数で実施される可能性があります。Teradata Databaseは、そのような計画はキャッシュしないことがあります。これは、キャッシュされた計画を後から実行する際には、キャッシュされている式の変更を処理するために、その計画を一般化する必要があるためです(パラメータ化されたリクエストを参照)。ただし、そのような条件を最適化する機会があります。例えば、この特定計画の実行用の値を使用してキャッシュされている計画から最終計画を構築するまで、行パーティション排除を遅延させることができます。
単一組み合わせパーティションを定義する等価条件
遅延行パーティション排除は、すべてのパーティション列のすべての行パーティション レベルにおける等価条件に、USINGリクエスト修飾子変数と組み込み関数を使用する際に発生します。つまり、システムがUSINGリクエスト修飾子変数または組み込み関数の値を適用して、キャッシュ可能な計画から最終計画を構築する際に、組み合わせパーティション式の単一の組み合わせパーティションが指定されるような制約が存在しなければなりません。
等価条件の一部は、定数条件である場合があります。パーティション式の形式では制限は定義されません。ただし、「パーティション列と次のいずれかの間には、単純な等価条件が必要である」という制限が等号制約の形式で存在します。
- USINGリクエスト修飾子変数
- 組み込み関数
- 定数式
組み合わせパーティション式の単一組み合わせ行パーティションが指定されるように、パーティション列でAND演算された等価条件が必要です。
例えば、次のテーブル定義があるとします。
CREATE TABLE markets ( productid INTEGER NOT NULL 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 (productid, region) PARTITION BY RANGE_N(region BETWEEN 1 AND 9 EACH 3) RANGE_N(business_sector BETWEEN 0 AND 49 EACH 10) RANGE_N(revenue_code BETWEEN 1 AND 34 EACH 2) RANGE_N(activity_date BETWEEN DATE '1986-01-01' AND DATE '2007-05-31' EACH INTERVAL '1' MONTH))
これは、行パーティション化を使用した書き換えの例で定義されたものと同じテーブルです。
説明を簡単にするために、問合わせ例に関する注釈では、以下の事項を前提としています。
- 行は組み合わせパーティション間で均等に配分される。
- 1つの行パーティション多数のデータ ブロックが存在する。
問合わせの例が遅延行パーティション排除を十分に活用できなかった場合、それらはすべて、別途指定がない限り、全AMPのフル テーブル スキャンを処理する必要があります。
この例では、2バイトの内部パーティション番号を想定しています。次のクエリーは、USINGリクエスト修飾子の値のセットと組み込み関数の両方を指定します。Teradata Databaseは全AMPで1つの組み合わせ行パーティションを読み取ります(述部内の条件がテーブルのすべての行パーティション化レベルに対するものであるために組み合わせされます)。この結果、システムはデータ ブロックの1/65,535のみをマーケット テーブルについて読み取ります。これは、述部で指定されている全パーティション レベルで、65,535のすべての組み合わせパーティションがスキャンに適格しますが、Teradata Databaseは、すべての適格な行にアクセスする際に、それらの65,535の組み合わせ行パーティションのうち、1つの組み合わせ行パーティションのみを読み取る必要があるためです。
組み合わせ行パーティションは、データ ブロックの途中で開始、終了することがあり、そのようなデータ ブロックには問合わせの述部によって修飾されない値を保持する行が含まれることがあります。Teradata Databaseは、組み合わせ行パーティションのデータ ブロックを読み取る際に、それらの行を必然的に読み取りますが、それらは問合わせの述部に対して適格でないので、結果セットでは返されません。
USING (r BYTEINT, b BYTEINT, rc BYTEINT) SELECT * FROM markets WHERE region=:r AND business_sector=:b AND revenue_code=:rc AND activity_date=CURRENT_DATE;
遅延行パーティション排除および文字パーティション化されたテーブル
パーティション行排除は、パーティション列をホスト変数を含むUSING変数と比較する条件を使用する際に、または、CURRENT_DATEのような組み込み関数を使用する際に実行される可能性があります。
最適化ルーチンが文字パーティション化されたテーブルに遅延行パーティション排除を適用するには、以下の条件が満たされている必要があります。
- すべての行パーティション レベルで最大で1つの文字パーティション列がある必要があります。
- セッション照合またはテーブル照合がMULTINATIONALまたはCHARSET_COLLのどちらかであり、いずれかのレベルのパーティション式内の非定数式を含む比較関数または文字列関数において大文字小文字が区別されない場合、セッション照合はテーブル照合と一致している必要があります。
遅延行パーティション排除の場合、次の関数および修飾子では大文字小文字が区別されません。
- LOWER
- SOUNDEX
- UPPER
- UPPERCASE修飾子
次の場合は、大文字小文字が区別されます。
- CHAR2HEXINT
- TRANSLATE
- TRANSLATE_CHK
- VARGRAPHIC
連結演算子は、大文字小文字が区別される、大文字小文字が区別されない、の両方であると見なされます。
次の関数は、比較演算子と同じルールに従います。Teradata Databaseは、関数入力と、ANSIまたはTeradataというセッション モードでデフォルトの大文字小文字の区別を調べて、大文字小文字の区別を判断します。
- INDEX
- MINDEX
- POSITION
SUBSTRING関数の存在は、大文字小文字の区別に影響しません。
- 遅延行パーティション排除のレベルを限定するWHERE句の条件で大文字小文字が区別されない場合、そのレベルのパーティション式のすべての比較で大文字小文字を区別しない必要があります。また、パーティション式の非定数式を含むすべての文字列関数で大文字小文字を区別しない必要があります。
条件内の非定数式を含むいずれかの比較関数または文字列関数の大文字小文字が区別されない場合、WHERE句の条件では大文字小文字が区別されないと見なされます。
遅延行パーティション排除のレベルを限定する等価条件で大文字小文字が区別されない場合、所定の行パーティション レベルでのすべての比較でも大文字小文字を区別しない必要があります。これはすべての行パーティション レベルに当てはまる必要がありますが、大文字小文字の区別は異なる行パーティション レベルで一致する必要はありません。
文字パーティション レベルに文字データの大文字と小文字を区別する比較が含まれる場合、対応するAND演算の等価条件(レベルのパーティション列を含む)でも大文字と小文字を区別する必要があります。
以下のテーブルを作成したとします。このテーブルはその後のSELECTリクエストの例で使用します。
CREATE SET TABLE user_IDs, NO FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL, CHECKSUM = DEFAULT ( user_ID INTEGER, user_name CHARACTER(40) CHARACTER SET UNICODE CASESPECIFIC) PRIMARY INDEX (user_ID) PARTITION BY RANGE_N(user_name BETWEEN 'A','Z','a','y' AND 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', NO RANGE OR UNKNOWN);
説明を簡単にするために、行パーティション間で行が均等に分散され、行パーティションごとに多くのデータ ブロックがあるとします。この形式の遅延行パーティション排除がないと、リクエストは要求された結果セットを返すために全AMP、フル テーブル スキャンが必要になります。
遅延行パーティション排除を使用するため、Teradata Databaseは全AMPで1つの行パーティションを読み取ります。システムは、組み込み関数USERの値をuser_nameに置き換えます。そのため、Teradata Databaseは、データ ブロックの約1/5(user_IDs用)だけを読み取る必要があります。
行パーティションが含まれているデータ ブロックには、それらのデータ ブロックの最初と最後に該当しない行が含まれていることがあるので、Teradata Databaseは行パーティションを読み込みながら、そのような行も読み込む必要があります。ただし、そのような行が結果セットの一部として返されることはありません。
SELECT * FROM user_IDs WHERE user_name=USER;