IBM Support

[Db2] パラメーターマーカー使用時の SQL パフォーマンス

Question & Answer


Question

同じ動的 SQL を実行しても、パラメーター・マーカーやホスト変数を使用すると、リテラル値を直接指定する場合よりもパフォーマンスが悪いことがあります。なぜですか。

Cause

Db2 は、実行要求された SQL 文、関連するオブジェクト (表や索引など) の構造、統計情報などを考慮して、最適と考えられるアクセスプランを選択します。
その際に検索条件に合致する行がどれくらいあるかを見積もり、その結果をもとに見積もりコストを計算します。

しかし、パラメーター・マーカーやホスト変数を使用している場合は、アクセスプラン選択時にはどのような値が代入されるか確定していないため、検索条件に合致する行数の見積もりができないことがあります。
その場合、SQL コンパイラーは代わりにあらかじめ決められた見積もり行数を使ってアクセスプランを選択します。
このため、パラメーター・マーカーやホスト変数を使用している場合は、リテラル値を直接指定する場合と比べて必ずしも最適なアクセスプランが選択されないことがあり、パフォーマンスが悪くなる可能性があります。

Answer

REOPT を使用してパラメーター・マーカーやホスト変数に代入される値を確定してからアクセスプランを選択できます。
動的 SQL の実行要求があった時に、代入値確定後最初に一回だけアクセスプランが選択させる (REOPT ONCE) か、または実行要求ごとに毎回アクセスプランを選択しなおすようにする (REOPT ALWAYS) ことができます。
ただし、REOPT ALWAYS はパラメーター・マーカーやホスト変数の使用によって本来は不要となる SQL のコンパイルを毎回行うため、適用にあたっては注意が必要です。
  • 組み込み SQL の場合 (パッケージごと)
    BIND (または REBIND) によってパッケージに REOPT オプションを指定します。
    BIND <バインド・ファイル名> [ REOPT ONCE または REOPT ALWAYS ]
    実行例
    $ db2 BIND package.bnd ACTION ADD REOPT ALWAYS
  • SQL プロシージャーの場合 (SQL プロシージャー単位)
    プロシージャーのパッケージに REOPT オプションを指定します。
    例:
    CALL SYSPROC.REBIND_ROUTINE_PACKAGE('P','<プロシージャ・スキーマ>','','<プロシージャ名>','REOPT ONCE')
    実行例
    $ db2 "call sysproc.rebind_routine_package('P','DB2INST1','','SP1','REOPT ONCE')"
  • 最適化ガイドラインで指定する場合 (SQL 単位)
    最適化ガイドラインが利用できる場合、ガイドラインで個別の SQL に REOPT を指定できます。
    インライン・ガイドラインで REOPT ONCE を指定する例
    SELECT * FROM T1 WHERE C1 = ? /*<OPTGUIDELINES><REOPT VALUE='ONCE'/></OPTGUIDELINES>*/
以下のインターフェースでは、事前に REOPT 用のパッケージを作成しておく必要があります。NULLIDR1 が "REOPT ONCE" に、NULLIDRA が "REOPT ALWAYS" に相当します。
$ db2 bind @db2cli.lst collection NULLIDR1
$ db2 bind @db2cli.lst collection NULLIDRA
  • CLI/ODBC アプリケーションの場合 (各クライアントの各データソースまたはすべてのデータソース)
    db2cli.ini の Reopt オプションを指定します。2: REOPT NONE、3: REOPT ONCE、4: REOPT ALWAYS
    [<DSN_name>]
    Reopt=[2|3|4]
    設定例 (SAMPLE データベースへの SQL で REOPT ONCE を有効にする)
    [SAMPLE]
    Reopt=3
    注:Db2 11.5.4 以降、db2dsdriver.cfg でも Reopt オプションを指定できます。
  • CLI/ODBC アプリケーションおよび .NET アプリケーションの場合 (各クライアントの各データソース)
    db2cli.ini もしくは db2dsdriver.cfg の CurrentPackageSet オプションで使用するパッケージを設定します。CurrentPackageSet と Reopt が両方指定された場合、CurrentPackageSet が優先されます。
    例1:db2cli.ini でデータソース SAMPLE に REOPT ONCE を設定
    [SAMPLE]
    CurrentPackageSet=NULLIDR1
    例2:db2dsdriver.cfg でデータベース SAMPLE にREOPT ONCE を設定
    <database host="db2srv.example.com" name="SAMPLE" port="50001">
     <parameter name="CurrentPackageSet" value="NULLIDR1"/>
    </database>
  • ユニバーサル JCC ドライバー タイプ 4 接続の場合 (JDBC アプリケーション接続単位)
    Connection または Datasouce の currentPackageSet プロパティで使用するパッケージを指定します。
    構成プロパティー db2.jcc.currentPackageSet でも同等の設定が可能です。
    例:構成プロパティーで REOPT ONCE を設定
    java -cp <class_path> -Ddb2.jcc.currentPackageSet=NULLIDR1 <appl_class>
    JDBCCollection プロパティーで使用するパッケージを設定できます。
    コード例:SAMPE データベースに REOPT ALWAYS を設定
    DB2SimpleDataSource db2ds = new DB2SimpleDataSource();
    db2ds.setDatabaseName("SAMPLE");
    db2ds.setUser("db2user");
    db2ds.setPassword("xxxxx");
    db2ds.setJdbcCollection("NULLIDRA");
    con = db2ds.getConnection();
運用上の考慮点
  • REOPT ONCE / REOPT ALWAYS のどちらを設定するかは、適用業務に依存します。
    REOPT ALWAYS を設定すると、SQL 実行ごとにアクセスプラン選択の処理が実行されますので、場合によってはかえってパフォーマンスを悪化させることがあります。一般的に、パラメーターマーカーやホスト変数に代入する値が実行ごとに大きく変わり、最適なアクセスプランがその都度異なるようなケースでは、REOPT ALWAYS が有利です。一方、代入値が実行ごとにそれほど変わらない場合は、REOPT ONCE によって最初の一度だけアクセスプランの選択を行い、以後は同じアクセスプランを再利用したほうが有利になります。
  • ステートメント・コンセントレーターを有効にすると、SQL のリテラルはホスト変数として扱われます。
    このため、REOPT ONCE の設定によりパフォーマンスが向上する可能性があります。
    注:REOPT ALWAYS を設定するとステートメント・コンセントレーターの意味が失われます。
[Db2] 最適化プロファイルの基本的な使い方 (IM-10-00P)
 
お問合せ先
技術的な内容に関して、パスポート・アドバンテージの契約のもと Db2 テクニカル・サポートへお問い合わせください。
Db2 テクニカル・サポート

[{"Line of Business":{"code":"LOB10","label":"Data and AI"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SSEPGG","label":"Db2 for Linux, UNIX and Windows"},"ARM Category":[{"code":"a8m500000008PkcAAE","label":"Compiler"}],"ARM Case Number":"","Platform":[{"code":"PF002","label":"AIX"},{"code":"PF010","label":"HP-UX"},{"code":"PF016","label":"Linux"},{"code":"PF027","label":"Solaris"},{"code":"PF033","label":"Windows"}],"Version":"All Version(s)"}]

Document Information

Modified date:
26 August 2023

UID

swg21572727