SELECT ステートメントには検索基準を満たす一連の行を定義します。 DB2 最適化プログラムは、 そのアプリケーションが修飾行をすべて検索することを想定しています。 OLTP およびバッチ環境においては、この想定が最も適しています。 しかし、"ブラウズ"アプリケーションにおいては、 照会で定義されている結果の集合が大規模であっても、 検索するのは最初のいくつかの行だけ、 通常は画面をいっぱいにするのに十分な数の行だけであるのが一般的です。
最適化プログラムによる省略時の設定 (すべての修飾行を検索する) は、 保管データの情報を更新または削除していないアプリケーションには最適とは言えません。
パフォーマンスが向上するように、 SELECT ステートメントを修正して結果表を限定または修正する方法は 4 つあります。 それらは、以下のとおりです。
FOR UPDATE 文節では、その後に置かれている UPDATE ステートメントが更新できる列を識別します。 FOR UPDATE 文節を列名なしで指定する場合は、 表または視点のすべての更新可能な列が含まれることになります。 列名を指定する場合、それぞれの名前は修飾されていてはならず、 表または視点の 1 つの列を識別している必要があります。
FOR UPDATE 文節は、次のどちらかが当てはまる場合は使用できません。
DB2 CLI 接続属性 SQL_ATTR_ACCESS_MODE を CLI アプリケーションで使用すると、 同じ結果を得ることができます。 詳しくは、コール・レベル・インターフェースの手引きおよび解説書 の SQLSetConnectAttr() のセクションを参照してください。
FOR READ ONLY 文節は、結果表が読み取り専用になることを保証します。 FOR FETCH ONLY 文節も同じ意味です。
結果表の中には、定義によって読み取り専用となっているものがあります。 たとえば、読み取り専用として定義されている SELECT ステートメントの結果表などです。 そのような場合でも FOR READ ONLY 文節を指定できますが、 文節の効果はありません。
更新と削除が許可されている結果表では、 FOR READ ONLY を指定すると、FETCH 操作のパフォーマンスが向上することがあります。 パフォーマンスが向上する可能性があるのは、 データベース・マネージャーがデータに対してブロック化 (排他ロックではない) を行うことができる場合です。 指定した UPDATE または DELETE ステートメントで照会が使用されている場合を除き、 パフォーマンスを向上させるには FOR READ ONLY 文節を使用する必要があります。
DB2 CLI 接続属性 SQL_ATTR_ACCESS_MODE を CLI アプリケーションで使用すると、 同じ結果を得ることができます。 詳しくは、コール・レベル・インターフェースの手引きおよび解説書 の SQLSetConnectAttr() のセクションを参照してください。
OPTIMIZE FOR 文節では、結果のサブセット 1 つだけを検索するのが目的なのか、 または最初の数行の検索を優先的に行うのが目的なのかを宣言する機構をアプリケーションに提供します。 この目的が理解されたら、最適化プログラムは、 最初の数行を検索するための応答時間を最小化するアクセス・プランを優先することができます。 さらに、単一ブロックとしてクライアントに送られる行数 (行のブロック化を参照) は、 OPTIMIZE FOR 文節の "n"という値によってバインドされます。 したがって、OPTIMIZE FOR は修飾行がサーバーによってデータベースから検索される方法と、 修飾行がクライアントに戻される方法の両方に影響を与えます。
たとえば、従業員表で基本給が最高の従業員を照会するとします。
SELECT LASTNAME,FIRSTNAME,EMPNO,SALARY FROM EMPLOYEE ORDER BY SALARY DESC
SALARY 列では降順索引を定義しました。 しかし、従業員の順序は従業員番号順になっているため、 給与索引のクラスター化が不十分であることが考えられます。 最適化プログラムは、多数のランダム同期入出力が行われないように、 修飾行の行識別子の分類を必要とするリスト事前取り出しアクセス方式 (リスト事前取り出しについてを参照) を使用することを選択します。 このため、最初の修飾行がアプリケーションに戻される前に遅延が起こります。 OPTIMIZE FOR 文節を次のようにステートメントに追加することにより、
SELECT LASTNAME,FIRSTNAME,EMPNO,SALARY FROM EMPLOYEE ORDER BY SALARY DESC OPTIMIZE FOR 20 ROWS
最適化プログラムは、おそらく、最高給を得ている 20 人の従業員だけを取り出すことを認識して、 SALARY 索引を直接使用することを選択します。 ブロック化された行数に関係なく、行のブロックは 20 行ごとにクライアントに戻されます。
OPTIMIZE FOR 文節を使用すると、最適化プログラムは、 大量データ操作または行の流れを妨げる操作 (分類など) を行わないアクセス・プランを行おうとします。 OPTIMIZE FOR 1 ROW を使用すると、アクセス・パスに最も影響を与えることになります。 結果として、この文節を使用すると、次のような効果があります。
OPTIMIZE FOR 文節はすべての最適化クラスに適用されますが (最適化クラスの調整を参照)、 最適化クラス 3 かそれ以上のクラスで最も効果的に作業します。 最適化クラスが 3 より下のクラスで貪欲型結合列挙方法 (最適結合を選択するための探索方式を参照) を使用すると、 最初の数行の素早い検索には役に立たない複数表結合のアクセス・プランになることがあります。
OPTIMIZE FOR 文節では、修飾行をすべて検索します。 しかし、修飾行をすべて検索するための合計経過時間は、 最適化プログラムが応答セット全体を最適化した場合よりも大幅に増える可能性があります。
コール・レベル・インターフェース (DB2 CLI または ODBC) を使用するパッケージ・アプリケーションがある場合は、 db2cli.ini 構成ファイルにある OPTIMIZEFORNROWS キーワードを用いて、 DB2 CLI に OPTIMIZE FOR 文節を各照会ステートメントの終わりに自動的に追加させることができます。 詳細については、コール・レベル・インターフェースの手引きおよび解説書 を参照してください。
データをニックネームから選択する場合、データ・ソース・サポートによって結果は異なります。 ニックネームによって参照されるデータ・ソースが OPTIMIZE FOR 文節をサポートしており、 DB2 最適化プログラムがこの文節を含む照会全体をデータ・ソースに後入れ先出しする場合、 この文節はデータ・ソースに送られたリモート SQL 内で生成されます。 データ・ソースでこの文節がサポートされていない場合、 または最適化プログラムがこの文節をローカルに実行することを決定する (コストが最低のプラン) 場合、 OPTIMIZE FOR 文節は DB2 でローカルに適用されます。 この場合、DB2 最適化プログラムは引き続き、 照会の最初の数行を検索する応答時間を最小限にするアクセス・プランを優先して選びますが、 プランの生成に最適化プログラムが利用できるオプションははっきり区切られず、 OPTIMIZE FOR 文節によるパフォーマンスの向上もほとんどありません。
FETCH FIRST 文節と OPTIMIZE FOR 文節の両方が指定されている場合は、 どちらか低い方の値が通信バッファー・サイズに影響を与えるものとして使用されます。 この 2 つの値は、最適化という目的のために独立して考慮されます。 これら 2 つの文節の相互関係について詳しくは、SELECT ステートメントの使用を参照してください。
OPTIMIZE FOR n ROWS 文節は、 すべての修飾行の検索を防止するわけではありません。 (修飾行をすべて検索するための合計経過時間は、 最適化プログラムが応答セット全体を最適化した場合よりも大幅に増える可能性があります。)
FETCH FIRST n ROWS ONLY 文節は、 SELECT ステートメント内から検索できる最大行数を設定します。 結果表を最初の数行に制限すると、パフォーマンスが向上します。 この文節が指定されていない SELECT ステートメントに基づく結果表に存在する行数にかかわりなく、 n 行だけが検索されます。
FETCH FIRST 文節と OPTIMIZE FOR 文節の両方が指定されている場合は、 どちらか低い方の値が通信バッファー・サイズに影響を与えるものとして使用されます。 この 2 つの値は、最適化という目的のために独立して考慮されます。 これら 2 つの文節の相互関係について詳しくは、SELECT ステートメントの使用を参照してください。
WITH HOLD 文節を含む DECLARE CURSOR ステートメントを指定してカーソルを宣言すると、 トランザクションがコミットされるときに、 すべてのオープン・カーソルは開いたままの状態になります。 さらに、WITH HOLD オープン・カーソルの現行カーソル位置を保護しているロックを除き、 すべてのロックが解放されます。
WITH HOLD 文節を含む DECLARE CURSOR ステートメントを指定してカーソルを宣言すると、 トランザクションが ROLLBACK で終了するときに、 すべてのオープン・カーソルは閉じます。 さらに、すべてのロックが解除されて LOB ロケーターが解放されます。
CLOSE CURSOR ステートメントの他の基本文節との比較については、 CLOSE CURSOR WITH RELEASEを参照してください。
DB2 CLI 接続属性 SQL_ATTR_CURSOR_HOLD を CLI アプリケーションで使用すると、 同じ結果を得ることができます。 詳細については、コール・レベル・インターフェースの手引きおよび解説書 の『SQLSetStmtAttr - ステートメントに関連したオプションの設定』を参照してください。
コール・レベル・インターフェース (DB2 CLI または ODBC) を使用するパッケージ・アプリケーションがある場合は、 db2cli.ini 構成ファイルにある CURSORHOLD キーワードを用いて、 DB2 CLI にすべての宣言されているカーソルについて WITH HOLD 文節が指定されているものと自動的に想定させることができます。 詳しくは、コール・レベル・インターフェースの手引きおよび解説書 のトランザクション構成キーワードのセクションを参照してください。