本コラムの対象:
JDBCを使用して、データベースプログラムを作成したことがある方。
1.はじめに
データベースの操作はその手法によってパフォーマンスに大きく影響をあたえます。特に、今日のシステム開発はデータベースなしに語れないほどであり、重要であると言えます。
ここでは、JDBCを使用したデータベース操作のトピックから、PreparedStatement を使用した高速化について説明します。このコラムで使用したサンプルでは、PreparedStatementの利用で最大3.8倍高速になりました。
2.Statementとは
Javaプログラムがデータベースに接続すると、対応するConnectionオブジェクトを一つ取得します。Statementは、「Connection(データベース接続)を使用してSQL文を送信するコンテナ」の役割を持ちます。
図1: データベースとJDBCの対応
上の図のようにしてユーザとクライアントプログラムを比べると、JDBCドライバはユーザが使用するプログラムであるとイメージできます。
3.Statementの種類
JDBCでは、以下の3種類のStatementがインタフェースとして定義されています。
・java.sql.Statement
・java.sql.PreparedStatement
・java.sql.CallableStatement(今回は割愛)
StatementとPreparedStatementの違いは、SQL文をあらかじめコンパイルしておくこと(これをプリコンパイルと言います)が可能であるかどうかにあります。この違いがあるため、一般にStatementよりもPreparedStatementを使用する方が高速であると言われています。
以下は、Oracle9iにおけるStatementとPreparedStatementの速度比較です。
(実験の詳細はこちら)

グラフ: StatementとPreparedStatementの速度比較(※上の図をクリックすると拡大します)
なぜ、上記のようにPreparedStatementは高速なのでしょうか?
4.PreparedStatementがStatementよりも高速になる理由
データベースでは、SQL文(ここではSELECT, INSERT, DELETE, UPDATEに限定します)を実行する際に、いくつかのステップを踏んで処理を行います。
(1) SQL文の構文チェック、権限チェック
(2) 検索方法の特定、コンパイル
(3) データの検索、変更を実施
ここで、多くのデータベースでは効率化の為に(2)の結果とSQL文をキャッシュに保存します。以降、キャッシュに存在するSQL文は検索方法が特定されているものとし、(2)を実施することなく(3)の処理に移れる為、効率的に処理をすることが可能になります。
ただし、実行するSQL文がキャッシュに保存されているSQL文にヒットする為には、文字列全体が「完全に一致する」必要があります。
例を挙げて考えてみましょう。
以下のSQL文 a) を実行すると、a) の文字列がキャッシュに保存されます。
a) SELECT * FROM A_TABLE WHERE ID=2
Statementを使用した場合は、SQL文を直接与えて実行する為、以下の b)、c) などはa) のキャッシュにヒットしません(図2の上側)。
■検索条件の値が異なるSQL文
b) SELECT * FROM A_TABLE WHERE ID=1
c) SELECT * FROM A_TABLE WHERE ID=5
一方で、PreparedStatementを使用した場合、SQL文を以下のように書くことが出来ます。
d) SELECT * FROM A_TABLE WHERE ID=? ← "?"はバインド変数
このようにSQL文を記述すると、データベースのキャッシュには上記 d) の文字列が保存されます。あとは、SQL文の実行時に"?"の値を1や5などいくつに決定しても、d) のキャッシュにヒットするようになります(図2の下側)。
このように、条件の値が異なる検索などではキャッシュの利用効率が上がる分、処理が高速になるのです。

図2: Statement と PreparedStatement の処理の違い
5.まとめ
以上から、繰り返し検索を行う場合はPreparedStatementが高速化の点で高い効果を発揮することがわかります。
実験結果からも、高速化率は検索ループ回数が増えるにしたがってより高くなっています。
実験したプログラムではSELECTのみでキャッシュを同じSQLの為だけに使用しましたが、追加や更新が発生する実際のシステムでも効果はあります。
PreparedStatementを使用するようにシステムを設計すると、例えば多数のアクセスが発生するようなシステムにおいても、負荷を低減できることでしょう。







Copyright (C) 2008 SMG Co., ltd. All Rights Reserved.