ページの先頭行へ戻る
Symfoware Server V12.1.x アプリケーション開発ガイド(JDBCドライバ編)
FUJITSU Software

2.6.2 ステートメントキャッシュ

ステートメントキャッシュとは

繰り返し実行されるループやメソッドの中でSQL文の準備、実行および解放が行われると、そのつど文の解析と作成およびカーソルの作成が行われます。

このような場合に、SQL文をキャッシュして再利用することで性能を向上させる機能です。

ステートメントキャッシュを利用すると、次のメリットがあります。

ステートメントキャッシュの仕組み

ステートメントキャッシュ機能は、prepareStatementメソッドまたはprepareCallメソッドで実行されたSQL文をキャッシュの対象にします。

ステートメントキャッシュ機能を有効にすると、以下のような動作となります。

  1. prepareStatementメソッドまたはprepareCallメソッドが実行されて、SQL文が作成されたときにキャッシュに登録します。

  2. PreparedStatementインタフェースまたはCallableStatementインタフェースのcloseメソッドが実行された、またはガーベジコレクションされたとき、キャッシュに登録されているSQL文を再利用可能な状態にします。

  3. 以降、prepareStatementメソッドまたはprepareCallメソッドが実行されるとキャッシュからSQL文を取り出して再利用します。

JDBCドライバはSQL文をキーにして同じSQL文かどうかを判断し、キャッシュを再利用します。以下の条件をすべて満足する場合に、同じSQL文であると判断します。

キャッシュへのSQL文の登録は、SQL文を実行した順番に行います。

ステートメントキャッシュに登録することができるSQL文の上限値は、データソースオプション設定画面の「ステートメントキャッシュ数」で設定します。

実行したSQL文の数が、「ステートメントキャッシュ数」に設定した値に達した場合、それ以降実行するSQL文はキャッシュしません。

データソースオプション設定画面の詳細については、“5.2.3 JDBCデータソース登録ツール”を参照してください。

性能が向上するケース

性能が向上するケースについて、記述例をもとに以下に説明します。

ケース1
PreparedStatement pstmt1 = null;                                 (1)
ResultSet rs1 = null;                                            (2)

pstmt1 = con.prepareStatement("SELECT ID,NAME                    (3)
                  FROM GENERAL.EMPLOYEE WHERE ID=?");
pstmt1.setInt(1, iNumber);                                       (4)
rs1 = pstmt1.executeQuery();                                     (5)
         :
rs1.close();                                                     (6)
pstmt1.close();                                                  (7)

以降、(3)~(7)の処理を繰り返し実行する。

上記のように、繰り返し実行される処理の中で、処理(3)のprepareStatementメソッドを毎回実行している場合、2回目以降はキャッシュに登録されたSQL文が再利用されるため、SQL文の解析と作成およびカーソルの作成が行われなくなり、性能が向上します。

ケース2
PreparedStatement pstmt1 = null;                                 (1)
ResultSet rs1 = null;                                            (2)
pstmt1 = con.prepareStatement("SELECT ID,NAME                    (3)
                   FROM GENERAL.EMPLOYEE WHERE ID=?");
pstmt1.setInt(1, iNumber);                                       (4)
rs1 = pstmt1.executeQuery();                                     (5)
          :
rs1.close();                                                     (6)
pstmt1.close();                                                  (7)

以降、(4)~(6)の処理を繰り返し実行する。

上記のように、繰り返し実行される処理の外で、処理(3)のprepareStatementメソッドを一度しか実行しない場合、コネクションプーリング機能と組み合わせることで、コネクションが再利用されたときに、以前のコネクションでキャッシュしていたSQL文が有効となるため、性能が向上します。

使用メモリ量について

ステートメントキャッシュ機能はSQL文をキャッシュするため、通常に比べてメモリ使用量が増加します。

使用するメモリ量については、以下を目安にしてください。

1文当たりのメモリ増加量 = 約100Kbyte

参照

アプリケーション全体のメモリ使用量については、“Interstage Application Server インストールガイド”を参照してください。

自動クローズオプション

PreparedStatementインタフェースまたはCallableStatementインタフェースのcloseメソッドが指定されている場合、ステートメントキャッシュ機能は、キャッシュに登録されたSQL文を再利用可能な状態にします。

しかし、closeメソッドを省略してガーベジコレクションにクローズを任せている場合には、キャッシュに登録されたSQL文を再利用可能な状態にするのが不定期となります。性能を向上するためには、アプリケーションでcloseメソッドを記述する修正が必要になります。

Symfoware ServerのJDBCドライバでは、アプリケーションを修正せずに自動クローズオプションを指定することで、以下の条件の場合にcloseメソッドを自動的に実行します。

  1. PreparedStatementインタフェースまたはCallableStatementインタフェースのcloseメソッドが実行されていない状態

  2. prepareStatementメソッドまたはprepareCallメソッドで同一のSQL文を指定

  3. 結果セットのタイプが同じ

  4. 結果セットの並行処理の種類が同じ

自動クローズオプションは、データソースオプション設定画面の「ステートメント自動クローズ」で設定することができます。

データソースオプション設定画面の詳細については、“5.2.3 JDBCデータソース登録ツール”を参照してください。

実行したSQL文の数が、「ステートメントキャッシュ数」で設定されたキャッシュ数に達した場合、以降実行されるSQL文はキャッシュしませんが、自動クローズの対象にもなりません。

注意

以下の記述例の処理(5)と(6)のように、prepareStatementメソッドで同一のSQL文を重複して使用している場合は、自動クローズオプションを使用しないでください。

PreparedStatement pstmt1 = null;                                 (1)
PreparedStatement pstmt2 = null;                                 (2)
ResultSet rs1 = null;                                            (3)
ResultSet rs2 = null;                                            (4)

pstmt1 = con.prepareStatement("SELECT ID,NAME                    (5)
                   FROM GENERAL.EMPLOYEE WHERE ID=?");
pstmt2 = con.prepareStatement("SELECT ID,NAME                    (6)
                   FROM GENERAL.EMPLOYEE WHERE ID=?");

pstmt1.setInt(1, iNumber);                                       (7)
rs1 = pstmt1.executeQuery();                                     (8)
          :
pstmt2.setInt(1, iNumber2);                                      (9)
rs2 = pstmt2.executeQuery();                                     (10)
          :

MAX_SQLまたはCLI_MAX_SQLとの関係

MAX_SQLまたはCLI_MAX_SQLを超える数のステートメントキャッシュをすることはできません。MAX_SQLまたはCLI_MAX_SQLを超えた場合には、アプリケーション実行時にエラーとなる場合があります。

MAX_SQLまたはCLI_MAX_SQLには、データソースオプション設定画面の「ステートメントキャッシュ数」で指定した数よりも大きい値を設定してください。

MAX_SQLについては、“5.2.3.5 クライアント用の動作環境ファイルの指定について”を参照してください。

CLI_MAX_SQLについては、“5.2.3.4 ctuneparamオプションについて”を参照してください。