- - PR -
JDBCでの配列フェッチについて
1
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-02-01 15:58
JDBCにて、SQLの結果を配列フェッチを行うことは可能なのでしょうか?
通常JDBCを用いて検索処理を行う場合、 java.sql.ResultSet rs = st.executeQuery(); while ( rs.next() ) { int nBookID = rs.getInt("BookID"); String strTitle = rs.getString("Title"); int nPrice = rs.getInt("Price"); } とループしてResultSetの値を格納すると思うのですが、 配列として件数を指定して、一気に値を格納したいと考えています。 どなたかご存知の方教えていただけないでしょうか? | ||||||||
|
投稿日時: 2004-02-02 11:28
配列フェッチをしたいという目的は何でしょうか? データベースアクセス回数を減らすことで、N/Wラウンドトリップ回数を減らし、パフォーマンスアップを図りたいということなら、ResultSet#setFetchSize(int) が使えます。 フェッチサイズがいくつであっても、JDBCコードは変更の必要はありません。 JDBCドライバが内部的に自動キャッシュするだけで、アプリケーションに対しては透過的に働くからです。 ただしこれがどう実装されるかはデータベースやJDBCドライバの種類によるかもしれないので、マニュアルなどで確認が必要だと思います。 もし単にJavaのループをなくしたいということであれば分かりません。 | ||||||||
|
投稿日時: 2004-02-04 01:44
ご回答ありがとうございます。
配列フェッチの目的は ・ループを使用しない。 ・カーソルDBアクセスの削減 による性能向上を考えていました。 ResultSet rs = st.executeQuery(); で実行した結果HITする件数が20,000件だったら、20,000件メモリにロードされるのですか? ※そんなSQLを発行するなと言うのは置いておいて。 もしそうなのであれば、今度はメモリ不足+FullGCが発生し性能低下を起こしそうですね。 通常は「ResultSet#setFetchSize」でフェッチのサイズを指定するものなのですかねぇ。 | ||||||||
|
投稿日時: 2004-02-04 02:37
どうも、配列フェッチの意味を間違えて使われてるような気がするのですが。 一般的な配列フェッチというのは、JDBCドライバがResultSetのnextメソッドを呼びたすたびに、 DBMSから結果を取得するのではなく、いくつかの行をまとめて取得することによって 性能を向上させることだと思うのですが。 この場合の配列フェッチは、あくまで、JDBCドライバ内部の動作なので、JDBCを利用する側からはResultSet#setFetchSizeを指定する以外普段の利用方法と変わりません。 くりおさんのいわれている配列フェッチとはそうではなくて、Queryの結果を 配列として受け取りたいということなのではないでしょうか。 もしそうだとすると、JakartaのDBUtilとかを使えば出来るかもしれませんが、 その場合、ふつうにJDBC使うより遅くなってしまいます(DBUtilならたいして遅くならないようですが)。
フェッチのサイズを指定してもたいして性能向上が期待できるとは思えないので ResultSet#setFetchSizeを使ったことはないです。 そんなに速度が問題になるなら、もっと別のチューニングを考えないとだめだと思います。 くりおさんのいわれている、20,000件ヒットするようなSQLを発行する必要が本当にあるのかどうか検討するのが先だと思うのですが。 | ||||||||
|
投稿日時: 2004-02-04 09:12
> くりおさんのいわれている、20,000件ヒッ>トするようなSQLを発行する必要が本当にあるのかどうか検討するのが先だと思うのですが。
同感です。 コンサルティングをやっていて、お客様から同様の要求があることがたびたびあります。 そのときに聞いているんですが、「では、その20,000件の中の12,345件目を見たい という要求はあるんですか?」 (つまり本当に必要なデータなの? 件数だけ見たいんなら別の取り方があるし。) | ||||||||
|
投稿日時: 2004-02-04 10:35
そこらへんは環境依存かなと思います。 データベースの種類や構成によっては、プリフェッチサイズを大きくすることで相当大きなパフォーマンスメリットがありますよ。 | ||||||||
|
投稿日時: 2004-02-04 14:43
本旨に沿っていないかもしれませんが、DBUtils についてです。
できます。各レコードを Object[]、Bean、Object[] を要素に持った List、Bean を要素に持った List などで受け取ることができます。スピードもあまり遅くならないようですよ。 参考: http://www02.so-net.ne.jp/~kikuta/dbu/ (ほか、日本語の情報はいくつかあります) しかし、これは該当全件をメモリ上に展開しようとするので「20,000件ヒットする SQL」には向きませんね。 # Iterator を返すハンドラを自作すればいいのだろうけれど。 DBUtils のソースは難しくなく改造して利用することも容易なので、ResultSet をガリガリいじり倒している人には試してみる価値があるかと思います。 | ||||||||
1
