複雑な照会で、REOPT バインド・オプションを入力変数と共に使用する

入力変数は、オンライン・トランザクション処理 (OLTP) 環境において、適切なステートメント準備時間を得る上で不可欠です。こうした環境では、ステートメントは単純になる傾向があり、照会アクセス・プランの選択はより簡単です。

異なる入力変数を使用して、同じ照会を複数実行する場合、動的ステートメント・キャッシュ内のコンパイル済みアクセス・セクションを再使用できます。こうして、入力変数が変わるたびに、コストがかかる SQL ステートメント・コンパイルをする必要がなくなります。

しかし、複雑な照会ワークロードの場合は、入力変数によって問題が引き起こされることがあります。このような場合、照会アクセス・プランの選択はより複雑になり、オプティマイザーは適切な決定をするためにより多くの情報を必要とします。 さらに、ステートメント・コンパイル時間は、多くの場合に合計実行時間のわずかな部分です。また、あまり繰り返されることがないビジネス・インテリジェンス (BI) 照会において、動的ステートメント・キャッシュは役立ちません。

複雑な照会ワークロードで入力変数を使用する必要があるなら、REOPT(ALWAYS) バインド・オプションの使用を検討してください。 REOPT バインド・オプションは、入力変数値が分かっている場合に、ステートメントのコンパイルを PREPARE 時から OPEN 時または EXECUTE 時まで遅らせます。 値は SQL コンパイラーに渡されて、オプティマイザーが選択可能性の見積もりをより正確に計算できるようになります。 REOPT(ALWAYS) は、毎回の実行ごとにステートメントを再コンパイルするように指定します。 REOPT(ALWAYS) は、WHERE TRANS_DATE = CURRENT DATE - 30 DAYS などの特殊レジスターを参照する複雑な照会でも使用できます。 入力変数により、OLTP ワークロードにおけるアクセス・プランの選択が良くない結果となり、REOPT(ALWAYS) のゆえに、ステートメント・コンパイルによる過剰なオーバーヘッドが引き起こされているなら、選択された照会のために REOPT(ONCE) の使用を検討してください。 REOPT(ONCE) により、最初の入力変数値がバインドされるまで、ステートメント・コンパイルが先送りされます。 SQL ステートメントは、この最初の入力変数値を使用して、コンパイルおよび最適化されます。 異なる値を使用する後続のステートメント実行では、最初の入力値に基づいてコンパイルされたアクセス・セクションが再使用されます。 この方法は、最初の入力変数値が後続の値を代表するものであるなら効果的です。また、入力変数値が不明な場合、デフォルト値に基づく照会アクセス・プランに比べ、より優れたプランが得られます。

REOPT を指定するには、幾つかの方法があります。
  • C/C++ アプリケーションの組み込み SQL の場合は、REOPT バインド・オプションを使用します。 このバインド・オプションは、静的 SQL と動的 SQL の両方における最適化のやり直し動作に影響を及ぼします。
  • CLP パッケージの場合は、REOPT バインド・オプションを使用して CLP パッケージを再バインドします。 例えば、分離レベル CS で使用する CLP パッケージを REOPT ALWAYS で再バインドする場合は、以下のコマンドを指定します。
    rebind nullid.SQLC2G13 reopt always
  • CLI アプリケーションの場合は、以下のいずれかの方法で REOPT 値を設定します。
    • db2cli.ini 構成ファイルで REOPT キーワード設定を使用します。 各値および対応するオプションは、以下のとおりです。
      • 2 = SQL_REOPT_NONE
      • 3 = SQL_REOPT_ONCE
      • 4 = SQL_REOPT_ALWAYS (SQL_REOPT_ALWAYS)
    • SQL_ATTR_REOPT 接続またはステートメント属性を使用する。
    • SQL_ATTR_CURRENT_PACKAGE_SET 接続またはステートメント属性を使用して、NULLID、NULLIDR1、または NULLIDRA パッケージ・セットのいずれかを指定する。 NULLIDR1 および NULLIDRA は、予約済みパッケージ・セット名です。 それらの値を使用すると、REOPT ONCE または REOPT ALWAYS がそれぞれ暗黙指定されます。 これらのパッケージ・セットは、以下のコマンドを使用して明示的に作成される必要があります。
      db2 bind db2clipk.bnd collection NULLIDR1
      db2 bind db2clipk.bnd collection NULLIDRA
  • IBM® Data Server Driver for JDBC and SQLJを使用する JDBC アプリケーションの場合、 DB2Binder ユーティリティーの実行時に -reopt 値を指定します。
  • SQL PL プロシージャーの場合、以下の方法の 1 つを使用します。
    • SET_ROUTINE_OPTS ストアード・プロシージャーを使用して、バインド・オプションを設定する。このオプションは、現行セッション内における SQL PL プロシージャーの作成に使用されるものです。 例えば、以下を呼び出します。
      sysproc.set_routine_opts('reopt always')
    • DB2_SQLROUTINE_PREPOPTS レジストリー変数を使用して、インスタンス・レベルで SQL PL プロシージャー・オプションを設定します。 SET_ROUTINE_OPTS ストアード・プロシージャーで設定した値は、DB2_SQLROUTINE_PREPOPTS の指定値をオーバーライドします。
以下の例に示すように、最適化プロファイルを使用して、静的ステートメントと動的ステートメントの REOPT を設定することもできます。
<STMTPROFILE ID="REOPT example ">
     <STMTKEY>
       <![CDATA[select acct_no from customer where name = ? ]]>
     </STMTKEY>
     <OPTGUIDELINES>
        <REOPT VALUE='ALWAYS'/>
    </OPTGUIDELINES>
</STMTPROFILE>