この付録では、Java Database Connectivity(JDBC)アプリケーションまたはアプレットの最適化の方法について説明します。内容は次のとおりです。
Oracle JDBCドライバは、Javaマルチスレッドを使用するアプリケーションを完全にサポートし、それに対応するように最適化されています。接続キャッシュによって提供されるアクセスなど、接続に対する制御されたシリアル・アクセスが必要であり、そのようなアクセス方法をお薦めします。ただし、複数スレッド間でのデータベース接続の共有はお薦めしません。複数のスレッドが1つの接続に同時にアクセスできないようにしてください。複数のスレッドで接続を共有する必要がある場合は、規則的な使用開始/使用終了の方法を使用してください。
マルチスレッド・アプリケーションでの作業時には、次の点に注意してください。
Connection
オブジェクトをローカル変数として使用します。
メソッドを終了する前にfinally
ブロックで接続をクローズします。たとえば、次のようになります。
Connection conn = null; try { ... } finally { if(conn != null) conn.close(); }
スレッド間でConnection
オブジェクトを共有しないでください。
同期は内部でドライバによって行われるので、JDBCオブジェクトを同期しないでください。
別のスレッドから時間がかかる問合せを取り消すのではなく、Statement.setQueryTimeout
メソッドを使用して問合せを実行する時間を設定します。
SELECT
、UPDATE
またはDELETE
などのSQL操作のためにStatement.cancel
メソッドを使用します。
COMMIT
、ROLLBACK
などのSQL操作のためにConnection.cancel
メソッドを使用します。
Thread.interrupt
メソッドを使用しないでください。
次の機能を使用すると、JDBCプログラムのパフォーマンスを大幅に向上させることができます。
自動コミット・モードは、SQL操作を実行するたびに自動的にCOMMIT
操作を発行するかどうかを、データベースに対して指示します。自動コミット・モードにすると、異なるバインド変数で同じ文を繰り返すような場合などに、時間と処理能力の面で大きな負荷がかかる場合があります。
デフォルトでは、新規の接続オブジェクトは自動コミット・モードが有効になります。ただし、接続オブジェクトjava.sql.Conection
またはoracle.jdbc.OracleConnection
のどちらかのsetAutoCommit
メソッドで自動コミット・モードを無効にできます。
自動コミット・モードでは、文が完了した時点または次の実行が発生した時点のうち、どちらか早い方でCOMMIT
操作が発生します。ResultSet
オブジェクトを戻す文の場合は、結果セットの最後の行が取り出されたとき、または結果セットがクローズしたときに文が完了します。より複雑なケースでは、1つの文で出力パラメータ値や複数の結果が返されることがあります。この場合、すべての結果および出力パラメータ値が取り出された時点でCOMMIT
が発生します。
setAutoCommit(false)
をコールして自動コミット・モードを無効にした場合、接続オブジェクトのcommit
またはrollback
メソッドを使用して、操作のグループを手動でコミットまたはロールバックする必要があります。
例
次に、ドライバをロードしてデータベースに接続する例を示します。新しい接続はデフォルトで自動コミット・モードが有効になるので、この例では自動コミットを無効にする方法を示します。この例では、conn
はConnection
オブジェクトを、stmt
はStatement
オブジェクトを表します。
// Connect to the database // You can put a database host name after the @ sign in the connection URL. OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:oracle:oci:@"); ods.setUser("HR"); ods.setPassword("hr"); Connection conn = ods.getConnection(); // It's faster when auto commit is off conn.setAutoCommit (false); // Create a Statement Statement stmt = conn.createStatement (); ...
Oracle JDBC接続オブジェクトや文オブジェクトでは、データベースにアクセスするたびにクライアントにプリフェッチする行数を指定できますが、結果セットは問合せ時に設定されます。接続オブジェクトに値を設定して、その接続で作成される各々の文に適用することも、任意の個別の文オブジェクト内でその値をオーバーライドすることもできます。接続オブジェクトのデフォルト値は、10です。クライアントにデータをプリフェッチすると、サーバーへのラウンドトリップの回数を減らすことができます。
JDBC 2.0では、同様かつさらに柔軟に、文オブジェクトにも(後続の問合せに影響)、結果セット・オブジェクトにも(行の再フェッチに影響)、1回のラウンドトリップでフェッチする行の数を指定できます。デフォルトでは、その結果セットを作成した文オブジェクトの値が、結果セットで使用されます。JDBC 2.0フェッチ・サイズを設定しないと、Oracle接続行プリフェッチ値がデフォルトとして使用されます。
セッション・データ・ユニット(SDU)は、Oracle Netがネットワーク間でデータを転送する前にデータを格納するバッファです。Oracle Netがバッファ内のデータを送信するのは、リクエストが完了したときか、バッファがいっぱいのときです。
SDUを構成すると、特に次の利点があります。
ネットワーク間でのSQL問合せおよび結果の転送に要する時間の削減
大量のデータの転送
注意: SDUサイズの設定を大きくすると、クライアント・プロセスおよびサーバー・プロセスのフットプリントは増加します。 |
関連項目: 『Oracle Database Net Services管理者ガイド』 |
この項の内容は次のとおりです。
データベース・サーバーのSDUサイズを設定するには、sqlnet.ora
ファイルでDEFAULT_SDU_SIZE
パラメータを構成します。
関連項目: データベース・サーバーのSDUサイズの設定の詳細は、『Oracle Database Net Services管理者ガイド』を参照してください。 |
JDBC OCIクライアントでは、Oracle Netレイヤーが使用されます。そのため、sqlnet.ora
ファイルでDEFAULT_SDU_SIZE
パラメータを構成すると、JDBC OCIクライアントのSDUサイズを設定できます。
関連項目: データベース・サーバーのSDUサイズの設定の詳細は、『Oracle Database Net Services管理者ガイド』を参照してください。 |
特定の接続記述子のDESCRIPTION
パラメータに指定すると、JDBC ThinクライアントのSDUサイズを設定できます。
sales.example.com= (DESCRIPTION= (SDU=11280) (ADDRESS=(PROTOCOL=tcp)(HOST=sales-server)(PORT=5221)) (CONNECT_DATA= (SERVICE_NAME=sales.example.com)) )
Oracle JDBCドライバでは、プリコンパイルされたSQL文のINSERT
、DELETE
およびUPDATE
の各操作をクライアントに蓄積し、サーバーに一括送信できます。この機能により、サーバーへのラウンドトリップの回数が低下します。
注意: バッチ・サイズを100以下の範囲に保つことをお薦めします。バッチが大きくなると、パフォーマンスはほとんど、またはまったく向上せず、実際には、大きなバッチを処理するために必要なクライアント・リソースのために、パフォーマンスが低下する可能性があります。 |
文キャッシュにより、繰り返しコールされるループやメソッドなどで何度も使用する実行文がキャッシュされるため、パフォーマンスが向上します。アプリケーションでは、特定の物理接続に関連付けられている文をキャッシュするために文キャッシュを使用します。文キャッシュを有効にすると、close
メソッドをコールするときに文オブジェクトがキャッシュされます。物理接続ごとに独自のキャッシュがあるため、複数の物理接続に対して文キャッシュを有効にすると複数のキャッシュが存在することになります。
注意: Oracle JDBCドライバは、Oracle文キャッシュで使用するために最適化されています。Oracle文キャッシュ(暗黙的または明示的)を使用することを強くお薦めします。 |
接続キャッシュで文キャッシュを有効にすると、基礎となる物理接続で有効な文キャッシュが論理接続で利用されます。接続キャッシュによって保持されている論理接続で文キャッシュを有効にしようとすると、例外が発生します。
SQL組込み型とはNUMBER
、CHAR
など、システム定義の名前を持つ型のことで、ユーザー定義の名前を持つ、Oracleオブジェクト、varrayおよびネストされた表型とは異なります。組込みSQL型のデータにアクセスするJDBCプログラムでは、プログラム・コンテキストによりSQLデータの変換先Java型が決定されるため、型変換はすべて一意です。
数値データにアクセスする最も効率的な方法は、int
、float
、long
およびdouble
などのプリミティブJava型としてアクセスする方法です。ただし、これらの型の範囲は、SQL NUMBER
データ型の値の範囲と正確には一致しません。このため、一部の情報が失われる可能性があります。値の範囲全体で絶対的な精度が必要である場合は、BigDecimal
型を使用します。
文字データはすべて、JavaのUCS2キャラクタ・セットに変換されます。文字データにアクセスする最も効率的な方法は、java.lang.String
としてアクセスする方法です。最も問題となるのは、データベース・キャラクタ・セットの2つ以上の文字が1つのUCS2キャラクタにマップされる場合に、情報が失われる可能性があることです。Oracle Database 11g以降、キャラクタ・セットのすべての文字がUCS2キャラクタ・セットの文字にマップされます。ただし、一部の文字はサロゲート・ペアにマップされます。