Symfoware Server アプリケーション開発ガイド(JDBCドライバ編) - FUJITSU -
目次 索引 前ページ次ページ

第2章 アプリケーションの設計> 2.6 省資源・高性能アプリケーション作成のために

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文はキャッシュしません。

データソースオプション設定画面の詳細については、“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. 結果セットの並行処理の種類が同じ

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

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

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

以下の記述例の処理(5)と(6)のように、prepareStatementメソッドで同一のSQL文を重複して使用している場合は、自動クローズオプションを使用しないでください。以下の例で自動クローズオプションを指定すると、処理(6)で処理(5)のSQL文がクローズされてしまい、処理(7)でエラーが発生します。
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)
          :

■CLI_MAX_SQLとの関係

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

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

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


目次 索引 前ページ次ページ

All Rights Reserved, Copyright (C) 富士通株式会社 2007