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
日本語 (日本)

Teradata Databaseには、CLIv2データ パーセル内のリクエストに含まれるパラメータ化された値(ユーザーが供給する定数データのUSINGリクエスト修飾子の値など)をピーク処理し、それらの変数を意味解釈ルーチンで解釈する機能があります。この機能により、キャッシュされた汎用計画を常に生成するよりも特定のキャッシュされない計画をリクエストに対して生成するほうがリクエストを処理する上でよいと判断された際に、最適化ルーチンで特定のキャッシュされない計画を生成することができます。

データ パーセル ピーク操作の用語

以下は、パラメータ値ピーク操作サブシステムに特有の用語です。

用語 定義
特定計画 最適化ルーチン プランは、そのクエリーの単一のインスタンスにのみ適用され、以下の任意のまたは両方を使用して生成されます。
  • パラメータ化された値のピーク処理およびCURRENT_TIMESTAMPおよびUSER組み込み関数
  • 中間増分計画および実行スプール結果の使用

単一インスタンス プランは特定の問合わせ計画と呼ばれます。Teradata Databaseが特定の問合わせ計画をキャッシュすることはありません。

パラメータ化されたリクエストでピーク処理をすることによって得られる値は、そのリクエストについての非常に限定された問合わせ計画を作成する際に使用できます。

特定計画は、静的計画と動的計画のどちらかになります。

汎用計画 その問合わせのインスタンスのすべてまたはほとんどに適用される、パラメータ化された値をピーク処理せずに生成された最適化プランおよびCURRENT_TIMESTAMPおよびUSER組み込み関数、中間増分計画および実行スプール結果、またはその両方。

汎用計画は静的計画です。

常に特定 パラメータ化された値は、後続のすべてのリクエストについて計画で解釈および評価されます。
常に汎用として処理される パラメータ化された値は、リクエストに対するコンクリート ステップが生成されるまで解釈されず、キャッシュされている汎用計画が後続のすべてのリクエストに対して使用されます。

リクエスト内にパラメータ化されたデータが存在している場合でも、最適化ルーチンが特定のリクエスト計画を生成するとは限りません。最適化ルーチンによって生成されるクエリー計画がパラメータ化された値に依存していない、パラメータ化されたクエリーが複数あります。このような問合わせでは、パラメータ化された値ピーク処理操作の結果として特定の問合わせ計画を生成することによる、付加的なパフォーマンスの向上は得られません。さらに、リクエストの実行時間が短い場合、計画をキャッシュしないことによるパフォーマンス低下の影響が大きくなることがあります。

例として、USINGリクエスト修飾子を指定する次の問合わせを検討します。そのUSINGリクエスト修飾子の単一の変数xは、WHERE句でパラメータ化された述部条件 :xを指定する際にも使用されます。

USING (x INTEGER)
SELECT *
FROM table_1
WHERE column_1 = :x;

table_1.column_1で定義されるUPI (Unique Primary Index: 固有プライマリ インデックス)がある場合、最適化ルーチンによって選択されるアクセス パスは、xの値に依存しません。これは、値に関係なく、その値が有効なプライマリ インデックスを指定し、プライマリ インデックスのアクセス パスが最良のアクセス パスであると仮定されているためです。

日付に基づくパラメータ値ピーク操作は、DATEおよびCURRENT_DATE組み込み関数の1つがリクエストで指定される場合に、これらから現在の日付を解釈します。また、これを使用して、テキストに存在する可能性があるその他のいくつかの要因に基づいて、特定または汎用の任意のの計画を生成することができます。これらの日付固有クエリー計画に使用される用語は、次のとおりです。
  • 問合わせ計画が生成された、解決済みのDATEまたはCURRENT_DATE値を持つ、汎用パラメータ化されたリクエストは、DateSpecific汎用計画と呼ばれます。
  • 問合わせ計画が生成された、解決済みのDATEまたはCURRENT_DATE値を持つ、パラメータ化された特定のリクエストは、DateSpecific特定計画と呼ばれます。

パラメータ値ピーク処理サブシステムについては、次の定義が適用されます。

用語 定義
パラメータ化されたPK文 OR演算条件のない単一テーブルの非パーティション テーブル、行パーティションPIテーブル、またはUSIの等価述部条件に使用されるパラメータ化された変数および/またはCURRENT_TIMESTAMP/USER組み込み関数のセットを含む単一のSQL文。

PKという用語は、一般にプライマリ キーを表わします。この場合は、プライマリ インデックス列セットまたは固有セカンダリ インデックス列セットを表わします。

パラメータ化されたPKリクエスト 以下のものだけが含まれるリクエスト。
  • パラメータ化PK文
  • null文

    Null文の定義については<Teradata Vantage™ - SQLデータ操作言語、B035-1146>を参照してください。

パラメータ化された値ピーク操作はパラメータ化されたPKリクエストの処理方法に影響しません。このため、この場合、最適化ルーチンは特定計画を生成しません。

次のテーブルは、さまざまなタイプのパラメータ化されたリクエストが、パラメータ化に依存するかどうかを示しています。

パラメータ化されたリクエストのタイプ 状態 理由
単純パラメータ化 パラメータ化された非依存 リクエストはPK文とその他の文で構成されています。ただし、述部のいずれにもパラメータ化された変数は指定されません。

例えば、次のテーブル定義があるとします。

    CREATE TABLE emp (
      emp_id INTEGER,
      dept_id INTEGER)
    UNIQUE PRIMARY INDEX (emp_id);

次の複文パラメータ化リクエストは、パラメータ化に依存しません。これは、:x変数がUPIで指定されているため、アクセス パスがxの値に依存しないためです。つまり、これは免除文であることを示しています(免除リクエストと非免除リクエストの除去を参照)。

USING (x INTEGER)
SELECT *
FROM emp
WHERE dept_id = 10
;SELECT *
FROM emp
WHERE emp_id = :x
AND   dept_id = 12;
パラメータ化されたPK パラメータ化された非依存 定義によります。
繰返し パラメータ化された非依存 定義によります。
その他のすべてのパラメータ化されたリクエスト パラメータ化された依存 定義によります。

パラメータ化された値ピーク操作

ピークという言葉は、パラメータ化された値をデータ パーセルから調べて、クエリー構文解析中に日付に基づいたCURRENT_TIMESTAMPまたはUSER組み込み関数の定数値を評価し、次にその値を使って以下のような潜在的な最適化機会を調査することを意味します。
  • 実現可能性および推移閉包(述部簡略化を参照)
  • 最適な単一テーブル アクセス計画
  • パーティション テーブルでアクティブな行パーティションの数が増えると、プライマリ インデックスのアクセスと結合のパフォーマンスが低下する場合もありますが、より細かな行パーティション排除が可能になります(詳細については、行パーティション排除を参照)。
  • 基本テーブルの代わりに、カバー セカンダリ インデックス、ハッシュ インデックス、および結合インデックスを使用(クエリー リライト、統計、および最適化を参照)

ピーク処理は、他の方法よりもリクエスト処理の早い段階で、問合わせに特定のデータ値を構文解析ツリーに挿入することによって、特定のカテゴリの問合わせを簡単に最適化することができます。キャッシュにあるクエリー計画を再使用すると構文解析と最適化の時間が短縮されるため、汎用計画は常にキャッシュされます。ただし、キャッシュにある汎用クエリー計画を再使用することは、特定リクエストに合わせて特定計画を生成する定数リテラルを提供するクエリーを実行するための常に最適な手法ではありません。

システムは、パラメータ化に依存するリクエストについての特定計画をキャッシュしません。これは、異なるセットのパラメータ化定数値または組み込み関数供給定数値を持つ他の同等のクエリーには、これらの計画を再使用できないためです。ただし、システムは、特定計画について生成される他の情報をキャッシュします。この情報には、そのSQLテキスト ハッシュ、ホスト文字セット、実行の見積もりコスト、構文解析時間、および実行時間が含まれます。

システムがリクエストの計画をキャッシュすべきでないと判断した場合は、そのデータを未知の値があるパラメータとして扱う代わりに、パラメータ化されたリクエストとDATE、CURRENT_DATE、TEMPORAL_DATE、CURRENT_TIMESTAMP、USER、および場合によってはTEMPORAL_TIMESTAMP組み込み関数値を使用して、リクエストを最適化することができます。つまり、パラメータ化された値ピーク操作により、パラメータ化されたリクエストと日付関連の組み込み関数、またはそれら両方からのリテラル データ値を使用して、最適化ルーチンが、汎用計画を生成して将来の再使用のためにキャッシュするのではなく、その特定のリクエストに関する最適かつキャッシュされない計画を生成することを確実にします。

最適化ルーチンによって生成される特定計画は最適な計画であり、その実行時パフォーマンスは、同等の汎用計画の実行時間よりも大幅に短縮されます。 ただし、特定計画とその同等の汎用計画の実行時コストにあまり差がない場合があります。 この場合、構文解析コストが高い場合は特に影響が大きくなります。 これらの問題を防ぐには、システムは構文解析と実行時間においてのこのようなリクエストをすべて監視し、リクエスト キャッシュ内に情報を保持します。 システムでは、この情報を使用して、リクエストに対する特定計画または汎用計画の生成の間で決定します。 このプロセスの詳細については、リクエスト キャッシュ ロジックを参照してください。

パラメータ化された値のピーク操作の有効化と無効化

デフォルトでは、パラメータ化された値ピーク操作が有効です。この機能を無効にするには、DBS制御ユーティリティを使用してDisablePeekUsingフィールドの値を変更します。 DBS制御の詳細については、<Teradata Vantage™ - データベース ユーティリティ、B035-1102>を参照してください。

パラメータ化された値ピーク操作についてのさまざまな検討事項

次に列挙されている項目もパラメータ化された値ピーク操作に影響します。
  • USNIGリクエスト修飾子がINSERT EXPLAINリクエストまたはDUMP EXPLAINリクエストと共に説明または実行依頼されている場合、データ パーセルもリクエストで提供されていれば、システムはパラメータ化された変数をピーク処理します。

    データ パーセルが実行依頼されていない場合、システムはパラメータ化された変数をピークせず、リクエストについての汎用計画を生成します。

  • パラメータ化されたリクエストがMultiLoadセッションまたはFastLoadセッションのもとで実行依頼される場合、システムはパラメータ化された変数と現在の日付をピーク処理しないため、リクエストのキャッシュ動作には影響がありません。
  • パラメータ化されたリクエストがFastExportセッションのもとで実行依頼される場合、データをエクスポートするための最適な計画を生成するために、システムはSELECTリクエストのパラメータ化された変数と現在の日付をピーク処理します。

    FastExportセッションで実行依頼されたリクエストはキャッシュされません。このため、パラメータ化されたリクエストの変数値をピーク操作してもキャッシュ動作には影響しません。

  • 構文解析プログラムが、パラメータ化されたリクエストのパラメータ化されたリクエスト変数のいずれの値もピーク処理しない場合は、キャッシュ動作には影響がありません。例えば、USING変数が最外部の選択リスト内にありWHERE条件で指定されていない場合などです。
パラメータ化された値ピーク操作により、次のようなパフォーマンスの向上を得られます。
  • 次の任意のの条件がTRUEの場合、Teradata Databaseはすべてのリクエストに対して特定計画を生成します。
    • 計画の見積もりを比較した結果、特定計画の見積もりコストが、汎用計画の見積もりコストより少ない。
    • 特定計画の構文解析コストと実行時CPUコストの両方が、同等の汎用計画の実行時CPUコストより小さい。
  • DATE、CURRENT_DATE、USERまたはTEMPORAL_DATE組み込み関数の値が展開され、最適化ルーチンに渡されて、最適な計画が生成されます(場合によっては、TEMPORAL_TIMESTAMP関数の値も展開され、最適化ルーチンに渡されます)。

    これはパラメータ化されたデータをリクエストが指定しない場合も同様です。

  • 特定計画を使用しても性能が向上しない場合、代わりに同等の汎用計画がキャッシュされ、それが後続のリクエストで再利用されます。
パラメータ化された値ピーク操作には、次のようなパフォーマンスに関する潜在的な短所がある場合があります。
  • 場合によっては、汎用計画と特定計画の見積もりが比較されます。汎用計画が同等の特定計画より悪い場合、そのリクエストはデータベースによって再び構文解釈され特定計画が生成されます。
  • パラメータ化に依存すると分類されているリクエストが、常に異なる特定計画を生成するとは限りません。そのようなリクエストはすぐにキャッシュされるのが理想的です。ただし、実際には、システムに2度目の実行依頼が行なわれた後にのみキャッシュされます。このため、2回だけ実行依頼されるリクエストにパフォーマンス上の影響を及ぼす可能性があります。
  • 特定計画と汎用計画が同等であり、特定計画に潜在的な利点が見つからない場合は、汎用計画がすべての後続のリクエストに対して使用されます。この結果、後続のリクエストのパラメータ化されたデータ値が、表出されリテラル データ値として計画に挿入された場合に、より適した特定計画をもたらす場合でも、性能上の利点を得ることはできません。

    ただし、リクエスト キャッシュが一旦除去されると、その影響を受ける特定計画と汎用計画がすべて再評価されます。

  • 汎用計画をキャッシュするかどうかの判断が、特定計画および汎用計画の実行経過時間に基づいて行なわれることがあります。システム上で実行中の他のワークロードが比較対象のいずれかのリクエストをブロックする可能性があり、これが原因で判断を誤る可能性があります。その結果、経過時間の値が不正確になることがあります。
  • 特定のコストと汎用コストを比較するアルゴリズムによって、見積もりが使用されることがあります。いずれかの計画の見積もりが不正な場合、キャッシュの判断に悪影響を与える可能性があります。

リクエスト キャッシュ ロジック

リクエスト キャッシュは正常に構文解析されたSQL DMLリクエストの計画を保存します。これらは、同じリクエストが再び実行依頼されるときに再利用できます。リクエスト キャッシュにはSQLリクエストのテキストとそのプラスチック ステップが含まれています。プラスチック ステップはリクエスト計画または単に計画と呼ばれます。

パラメータ化された値ピーク操作が有効でない場合、パラメータ化されたリクエストが検出されます。これらが正常に構文解析されると、すぐにキャッシュされます。パラメータ化された値ピーク操作は、CLIv2実行または準備および実行の両方のモードで実行依頼されるリクエストについて、リクエスト キャッシュの動作を次のように変更します。
  • リクエストがDATE、CURRENT_DATE、TEMPORAL_DATE組み込み関数を指定する場合、リクエストが構文解析される際に、特定の日付について計画が生成されます。特定の日付が最適化プロセスの間に表出されると、最適化ルーチンによってより最適な計画が生成されます(適用可能な場合)。

    例えば、パーティション式が日付ベースの場合、述部のパーティション列の条件によってCURRENT_DATE組み込み関数が指定され、最適化ルーチンによって行パーティション削除が実行され、より最適な計画が生成されます。

    テーブルt4は、日付列dで行パーティション化されている場合について示しています。

    EXPLAIN SELECT *
            FROM t4
            WHERE d BETWEEN DATE '2005-02-01' AND CURRENT_DATE;

    次に、日付が置き換えられない場合のEXPLAINテキスト出力の該当部分を示します。

    ...
    3) We do an all-AMPs RETRIEVE step from 23 partitions of MYDB.t4
       with a condition of ("(MYDB.t4.d <= DATE) AND (MYDB.t4.d >= DATE
       '2005-02-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 2 rows. The estimated time for this step is 0.09 seconds.
    ...

    CURRENT_DATEの値をピーク処理しないでこの問合わせを処理するには、Teradata Databaseが23行のパーティションをスキャンしなければならないことに注意してください(これに関連するテキストは太字で強調表示されています)。

    パラメータ化された値ピーク操作が有効な場合、同じリクエストについてのEXPLAINテキスト出力の該当部分は次のようになります。このEXPLAIN出力では、パラメータ化された値ピーク操作によって、スキャンする行パーティションが23 よりも 9少なくなっている点に注目してください(これに関連するテキストは太字で強調表示されています)。

    ...
    3) We do an all-AMPs RETRIEVE step from 14 partitions of MYDB.t4 
       with a condition of ("(MYDB.t4.d <= DATE '2006-03-02') AND
       (MYDB.t4.d >= DATE '2005-02-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 2 rows. The estimated time 
       for this step is 0.08 seconds.
    ...

    日付ベースの計画は、日付と共にリクエスト キャッシュに格納されます。Teradata Databaseはこの情報を使用して、次のテーブルに説明されているように再発行されたリクエストを処理します。

    システムは最初に日付を再計算します。

再計算された日付 結果
キャッシュされている日付に一致する場合 キャッシュされている計画が再利用されます。
キャッシュされている日付に一致しない場合 キャッシュされている計画は除去され、変更された日付について新しい計画が生成されます。

その後、新しい計画がキャッシュされます。

  • パラメータ化された値ピーク操作が有効な場合、次のテーブルに示すように、リクエストがキャッシュされる場合とされない場合があります。
パラメータ化されているDMLリクエストの状態 結果
パラメータ化された非依存 即座にキャッシュされます。
パラメータ化された依存 表示されているピーク処理済みのパラメータ化された値によって構文解析され、最適化ルーチンが、それらのパラメータ化された値に特有の計画を生成します。

この場合、計画はキャッシュされませんが、そのリクエスト テキストはキャッシュされます。

同一のパラメータ化に依存するリクエストが再び実行依頼されると、最適化ルーチンはそれについての汎用計画を生成します。

次の文のいずれかがTRUEの場合、汎用計画が実行されます。
  • 見積もりが比較されない。
  • 特定計画の見積もりが、汎用計画の見積もりと比較しても何の利点も示さない。

それ以外の場合は、データベースがリクエストを再度構文解析して、それについて特定計画を生成します。

これは、次の文の任意のがTRUEの場合、実行された汎用計画は、将来の再利用に備えて常にキャッシュされるという意味です。
  • 実行時CPUコストが非常に小さい。
  • 特定計画を実行しても、構文解析CPUコストを補償するのに十分な実行時CPUコストの利点が得られない。

その他のすべての場合、最適化ルーチンはキャッシュが除去されるまですべてのリクエストについて特定計画を生成します。これには汎用計画の実行が失敗する場合、例えば実行中に異常終了したり致命的なエラーを返す場合が含まれます。

システムで対象のリクエストに関してその後の実行依頼すべてについて特定計画を生成する場合は、パフォーマンスの向上が期待できます。システムで対象のリクエストに関してその後の実行依頼すべてについてキャッシュに入っている計画を使用する場合は、パフォーマンスの向上が期待できます。

MONITOR SESSIONリクエストを実行依頼して、セッションでのリクエスト キャッシュのヒットの数を確認できます。この情報を使用して、汎用計画がキャッシュおよび使用されているかどうかを確認できます。

特定計画は、そのパラメータ化された値がリテラルの代用となっているため、一般に同等の汎用計画よりも適しています。ただし、特定計画のコストが、同等の汎用計画のコストと同じであるリクエストが一部存在します。特定計画を生成するために、パラメータ化された値を置き換えるロジックでは、見積もられている特定計画の時間と汎用計画の時間が同じである問合わせを区別することはできません。

次の2つのリクエストのリクエスト計画は同等であり、パラメータ化された値をピーク処理しても、これらのリクエストに最適な計画を生成することはできません。ただし、次のような結合インデックスがクエリーについてのターゲット基本テーブルで定義される場合、以前のSELECTの例などのリクエストは、パラメータ化された値ピーク操作によるメリットがあります。

例えば、次のテーブル定義があるとします。

CREATE SET TABLE MYDB.t2, NO FALLBACK,NO BEFORE JOURNAL,
  NO AFTER JOURNAL,CHECKSUM = DEFAULT (
  i INTEGER,
  j INTEGER,
  k INTEGER,
  l INTEGER,
  c CHARACTER(400) CHARACTER SET LATIN NOT CASESPECIFIC
                   DEFAULT 'a')
PRIMARY INDEX (i)
INDEX (j);

テーブルに示されている統計は、NUSI (非固有セカンダリ インデックス)列jおよびNUPI (非固有プライマリ インデックス)列iの固有の値の数を示しています。

Date     Time     Unique Values      Column Names
-------- -------- ------------------ --------------------------
06/02/17 12:51:22              1,537 j
06/02/17 12:56:10                 60 k

関連するステップを示しながら、テーブルt2に対する次のクエリーについて考えてみます。

EXPLAIN USING (a INTEGER) SELECT *
                          FROM t2
                          WHERE j = 58
                          AND   k = 100000+i;

...
3) We do an all-AMPs RETRIEVE step from MYDB.t2 by way of an all-rows
   scan with a condition of ("(MYDB.t2.k = (100000 + MYDB.t2.i )) AND
   (MYDB.t2.j = 58)") into Spool 1 (group_amps), which is built
   locally on the AMPs. The size of Spool 1 is estimated with high
   confidence to be 10 rows. The estimated time for this step is
   0.17 seconds.
...

次に、関連するステップを示しながら、テーブルt2に対する次のクエリーについても考えてみます。

EXPLAIN USING (a INTEGER) SELECT *
                          FROM t2
                          WHERE j = 58
                          AND   k =:a + i;

...
3) We do an all-AMPs RETRIEVE step from MYDB.t2 by way of an all-rows
   scan with a condition of ("(MYDB.t2.k = (:a + MYDB.t2.i )) AND
   (MYDB.t2.j = 58)") into Spool 1 (group_amps), which is built
   locally on the AMPs. The size of Spool 1 is estimated with high
   confidence to be 10 rows. The estimated time for this step is
   0.17 seconds.
...

テーブルt3を、テーブルt2のデータを含むコピーとして作成し、次の結合インデックス定義について考えてみます。

CREATE JOIN INDEX j1 AS
  SELECT *
  FROM t3
  WHERE j > 58
  AND k > i+3;

次のクエリーについて考えてみます。ここでは、a1USING値は4であると仮定します。

EXPLAIN USING (a1 INTEGER)
        SELECT *
        FROM t3
        WHERE j = 80
        AND   k = i+:a1;

値の4がステップ3のテキストに明示的に挿入されていることを確認できます。該当箇所は太字で強調表示されています。

...
3) We do an all-AMPs RETRIEVE step from MYDB.J1 by way of an 
   all-rows scan with a condition of 
   ("(MYDB.J1.k = (MYDB.J1.i +  4  )) AND
   (MYDB.J1.j = 80)") into Spool 1 (group_amps), which is built
   locally on the AMPs. The size of Spool 1 is estimated with no
   confidence to be 126 rows. The estimated time for this step is
   0.14 seconds.
...