- PR -

OracleDataReaderのReadメソッドについて

投稿者投稿内容
me2kichi
会議室デビュー日: 2007/10/02
投稿数: 15
投稿日時: 2007-10-04 09:48
VS2005(VB) + OracleでWinアプリを開発しています。

Select文の結果が返ってくるまでに、
時間がかかるものは、強制的に接続を切断するように、

OracleDataReader = OracleCommand.Executereader

While OracleDataReader.Read()

として、一定の件数に達すれば、接続を切断するようにしています。

しかし、Select文によっては、OracleDataReader.Read()メソッドだけで、
1分以上かかってしまうものがあります。

OracleDataReader.Read()メソッドの処理を高速化することは可能でしょうか。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-10-04 10:40
抽出結果自体の件数が多すぎなのではないでしょうか。
前スレと同じ流れになりそうですね。どうせ打ち切るのならば、最初から件数分で打ち切った方がコストが低いと思います。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
もしもし
ぬし
会議室デビュー日: 2004/10/15
投稿数: 280
投稿日時: 2007-10-04 10:44
実際に実行している SQL ってわかりますかね。
そのチューニングとかアクセス対象のオブジェクトをチューニング(索引とか統計情報とかその他)データベースそのもののチューニングとかが必要になるかと。

_________________
もしもし@RMAN 友の会
me2kichi
会議室デビュー日: 2007/10/02
投稿数: 15
投稿日時: 2007-10-04 12:41
じゃんぬさん、またまた、ありがとうございます。

Oracleに特化した問題だと思いましたので、
別レス立てました。

引用:

どうせ打ち切るのならば、最初から件数分で打ち切った方がコストが低いと思います。



について、質問ですが、
OracleDataReader.Read()部分(恐らくフェッチ)に時間がかかっているので、
件数で打ち切る等は関係ないと思うのですが・・・。

それとも、OracleDataReader.Read()でフェッチする行数(件数)を決めておけるのですか。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-10-04 13:42
引用:

me2kichiさんの書き込み (2007-10-04 12:41) より:

OracleDataReader.Read()部分(恐らくフェッチ)に時間がかかっているので、
件数で打ち切る等は関係ないと思うのですが・・・。


そもそも Read メソッドの部分について言及しているのではなく、もっと前の段階の話をしますから関係ありません。 "最初から" と書いていますがそういう意味です。 (さすがに... Read メソッドが遅いといっているのに、"Read で対策せよ" なんてバカな回答はしませんよ...)

再度同じことを書きますが、

> 抽出結果自体の件数が多すぎなのではないでしょうか。

Read メソッドは抽出結果を順次 Read してくれる常時接続型のオブジェクトです。 この時点で遅いのですから、当然もっと前の段階の話をしています。 Read メソッドではなく ExecuteReader メソッドの段階でという意味です。

ただ推測が多分に入っておりますので断定は難しいです。 私は件数が問題ではないかと推測しているのですが、そのあたりの検証状況がわかりません。 問題解決のためにさまざまな検証をされているかと思いますが、そのあたりの状況や結果を教えて頂けませんか?

私が me2kichi さんの立場にあれば、段階を踏んで件数を加増して挙動がどう変わるのかを見て 「問題の切り分け」 をします。 問題の切り分けこそが問題解決の基本です。 森の中を彷徨って 'てんとう虫' を捜すより、'てんとう虫' がいると予めわかっている 1 本の木から 'てんとう虫' を捜した方が早いですから。

--

その前にもしもしさんの仰っていることを確認した方がいいですね。 そのあたりの可能性を考慮していませんでした。 もしやテーブルに何もキーが設定されていないなんてことはないですよね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
さかもと
ぬし
会議室デビュー日: 2004/05/14
投稿数: 586
投稿日時: 2007-10-04 13:47
さかもとと申します。

前スレからの続きですが、件数で絞る方が、と。

件数で絞るというのは

SELECT 色々と難しい文 FROM XXXX
LEFT OUTER JOIN XXXX
WHERE 何か条件

とこれに対してRead&カウントでははく

最初に
SELECT COUNT(何か)FROM XXXX
LEFT OUTER JOIN XXXX
WHERE 何か条件
※とにかくコストが掛けず簡単に件数を求めるSQL文

で件数を出しておき、例えばそれが1000件以上だったらReadの処理をさせず、条件の見直しをユーザーに知らせるとか。

そういうことではないかと思います。


あっ、席を外している間に・・・。
_________________
------------------------------------------
拝啓、さかもとと申します。

[ メッセージ編集済み 編集者: さかもと 編集日時 2007-10-04 13:48 ]
さかもと
ぬし
会議室デビュー日: 2004/05/14
投稿数: 586
投稿日時: 2007-10-04 14:00
さかもとです。

コード:

Dim hogeCount As Integer
'何かしらのSQL文件数確認用
cmd.CommandText = "SELECT COUNT(hoge) FROM tableHoge"  

'hogeCount=対象となる件数
hogeCount = CInt(cmd.ExecuteScalar) 'ExecuteReaderではなくExecuteScalar

If hogeCount>1000 Then
Exit Sub '1000件以上だったら処理を抜けるとか
End If

'処理を抜けなかったらReadの処理をする
cmd.CommandText = "SELECT Item1,Item2,Item3 FROM tableHoge"

dr = cmd.ExecuteReader
While dr.read
'何かの処理
End While



かなり省略してますが、このような流れではダメでしょうか?



こっ、これか・・・。
w→s
_________________
------------------------------------------
拝啓、さかもとと申します。

[ メッセージ編集済み 編集者: さかもと 編集日時 2007-10-04 15:39 ]
me2kichi
会議室デビュー日: 2007/10/02
投稿数: 15
投稿日時: 2007-10-05 14:57
じゃんぬさん、こんにちは。

うまく説明できるかどうか分かりませんが、返答いたします。

まず、私が「件数で打ち切る等は関係ないと思うのですが・・・。 」
と書いたのは、
単一のテーブルでのSQLで、結果が1万件よりも、複数で外部結合を多用している
SQLの500件の方が、Read()の時間が遥かに時間がかかっていたからです。

後から読み返してみて、自分が持っている情報をきちんと伝えていないまま、
質問をしていました。この点に関しては、申し訳ないと思っています。

さかもとさん、フォローありがとうございます。
さかもとさんから指摘いただいた、count() SQLを別で作成する方法だと、
SQLの内容が変わっても、以前ほどパフォーマンスのバラツキがなくなりました。

あとは、count()用のSQLの余分な外部結合をはずせば、より良いものになりそうです。

最後に、もしもしさん、返事が遅れてしまいました。
SQLに関しては、explainplanでindexが効いているか、確認しているので、問題ありません。

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