- PR -

Java実装時のレスポンス悪化について

投稿者投稿内容
Msa
会議室デビュー日: 2003/10/22
投稿数: 5
投稿日時: 2003-12-12 13:42

ある検索機能を、Javaで実装しています。
DBへのアクセスは、PreparedStatementを使用して、
SQL文を生成して、executeQueryメソッドを実行し、
RecordSetを取得しています。

ここで問題をなっているのは、
Javaで実行しているSQL文を抜き出してSQLPlusで実行した場合は、
1秒以内でレスポンスが帰ってくるのに、
Javaアプリ内部で実行した場合は、
executeQueryメソッド発行後、ノーレスになってしまいます。

SQL文生成時に、NUMBER型の引数にもかかわらず、
PreparedStatement.setString()
となっている個所を修正したら、いったんは早くなったのですが、
数日後、再度レスポンスが悪化しました。

皆さんはこのような現象に遭遇した事はありますか?
何かご存知でしたら、助言をお願い致します。
よろしくお願いします。

環境は以下の通りです。
DB:Oracle9i
JDK:1.3.1_09
JDBCドライバ:Oracle OCI Driver 9.0.1
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2003-12-12 15:45
まず Java にすると動かないという問題から。

Connection, Statement, ResultSet のライフサイクルと、それぞれの間の依存性はおわかりですか?
それぞれのリソースを使い終わったらちゃんと後始末をしないと期待しない動作になります。
(確か他の RDBMS ではこの辺が非常にシビアでしたが、Oracle は割と寛容と言うか、ライフサイクルがきちんと管理されていないプログラムでも、ドライバが頑張ってくれるのか、なんだか動いてしまうということはあります)

次に型が違っている問題ですが、これもとりあえずは動くものの、DB の内部を監査すると異常な状態を引き起こしているかもしれません。
これについては、そちらの DBA 権限者の方に尋ねられた方がネットよりは非常に良いと思います。

的確に回答するために必要な情報量が掲示板でやりとりするには大きい上、次はどこを調べるかなど、頻繁なやりとりも要求されるでしょう。私見ですが、ご自分で Oracle や JDBC の勉強を進められた方が早いようにも感じます。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2003-12-12 15:57
私はそのような現象に出会ったことはないのですが。

PreparedStatement.setString()を直してパフォーマンスがよくなったのは暗黙の型変換がなくなったのでSQL解析のコストが下がったからだと思うのですが、その数日後に悪くなったというのはよくわかんないですね。おそらくOracleの問題なのでしょうが。

>>数日後、再度レスポンスが悪化しました。
これはどのくらい遅くなったんですか?
Msa
会議室デビュー日: 2003/10/22
投稿数: 5
投稿日時: 2003-12-12 16:12
返信ありがとうございます。

レスポンスは、検索結果表示まで2〜3秒かかっていたものが、
5分以上かかるようになってしまいました。

ご指摘のあった、各種リソースの後始末については、
そのあたりが一番怪しいと思って確認したのですが、
問題は見つかりませんでした。

永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2003-12-12 18:33
永井です。

(Javaからの)DBへの問い合わせレスポンスが悪いという件に関してですが、
私の経験したことのある例ですと……

1. インデックスを使っていなかった
2. 暗黙の型変換が行われていた
3. 大量の結果が返る2つの問い合わせをUNIONしていた
4. 非常に大量の結果が返る問い合わせだった

……などがあります。

1、2、3に関しては、SQLPlusで実行しても出る問題ですので
今回は関係無さそうですが。
#2はMsaさんの方で修正された問題点と同じですね

残っているのは4になりますが……私の場合は200万件くらい
返ってくるSQLを発行してしまった際に、(ほとんど)動かなくなりました。
じりじり動いてはいたような気はするんですが……
#そのときは取得したものをファイルに出力していました

対象レコードが数日間で爆発的に増大してしまったというような
ことはないでしょうか?

余談になりますが1〜3それぞれの解決方法としては……
1→インデックスを使うようにする
2→暗黙の型変換が発生しないよう、正しい型で与える
3→重複しないことが分かっているなら、替わりにUNION ALLを使う
となります。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2003-12-12 19:07
ところで何件ぐらいの問い合わせなんでしょうか?
Msa
会議室デビュー日: 2003/10/22
投稿数: 5
投稿日時: 2003-12-12 19:24
いろいろご意見ありがとうございます。

戻される行数は50行程度なのですが、
その結果を得るために、
数百万行のテーブルをぶつけています。

SQL実行計画を分析したりもしているのですが、
SQLPlusでのレスポンスは悪くないので、
では、Javaのアプリが何か悪さしてるのかな・・・と思っていました。

うーん。やっぱりSQL自体に問題があるのですかねぇ。。。
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2003-12-12 19:48
引用:

Msaさんの書き込み (2003-12-12 19:24) より:
いろいろご意見ありがとうございます。

戻される行数は50行程度なのですが、
その結果を得るために、
数百万行のテーブルをぶつけています。

SQL実行計画を分析したりもしているのですが、
SQLPlusでのレスポンスは悪くないので、
では、Javaのアプリが何か悪さしてるのかな・・・と思っていました。

うーん。やっぱりSQL自体に問題があるのですかねぇ。。。



この状況から考えると、やはりPreparedStatementに値をBindする際に
違った型で指定してしまって……というのが、ありそうな気がしてきます。

もう一度見返されてはいかがでしょうか?

と……ふと思ったのですが、SQLPlusに貼り付けて「素早いレスポンスが
確認出来ているSQL文」をPreparedStatementのSQLとして直で指定しても
反応は遅いですか?
#PreparedStatementに対するBindをコードで行わず、条件句に出てくる
#数値や文字列もそのまま記入したSQL文を使用した場合でです

スキルアップ/キャリアアップ(JOB@IT)