- PR -

ODP.NET での LOB データ取得について

1
投稿者投稿内容
ケビン
会議室デビュー日: 2007/04/12
投稿数: 15
投稿日時: 2007-05-26 23:18
VisualStudio 2005(SP1/C#.NET) と ODP.NET を使用して、
プログラムを作っています。

下記の参考サイトをもとに、BLOB フィールドに格納された
画像データを取得するプログラムを作ってみました。
テーブル(SAMPLE_TBL)は画像名称(NAME)を VARCAHR2(128) 、
画像データ(IMAGE)を BLOB で格納するように設計してみました。
このテーブルに 1000 件のレコードを格納します。
このとき格納する画像はサイズの大きなデータと小さなデータを
交互に格納するようにします。


そしてプログラムでは、テーブルに格納された画像データを
読み込むようにコーディングしてみたんですが、このとき、
参考サイトにある、「LOBデータ取得時のパフォーマンス・チューニング」の方法で、
GetBytes() メソッドを使って読み込んでみたんですが、
ある程度レコードを読み続けていると、ある一定のポイントで、
内容が一部欠落してしまう現象が確認されました。
確かに一度に読み出すサイズをコントロールすれば高速に感じているのですが、
そもそも複数のレコードを取得するときに GetByte() メソッドを使って
良いものなのかどうか、というのが悩みの種になっています。

この問題についてご教授願えればと思います。


(参考サイト)
http://www.atmarkit.co.jp/fdb/rensai/odpdotnet03/odpdotnet03_1.html


[ メッセージ編集済み 編集者: ケビン 編集日時 2007-05-26 23:19 ]

[ メッセージ編集済み 編集者: ケビン 編集日時 2007-05-30 08:10 ]
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2007-05-30 23:19
データが欠落するということは一度の GetBytes メソッドでは読み込み切れなかったということではないでしょうか?
GetBytes メソッドの返却値は 読み込んだバイト数なので、期待したバイト数に達していなかったらもう一度 GetBytes する必要があると思います。

_________________
かるあ のメモスニペット
ケビン
会議室デビュー日: 2007/04/12
投稿数: 15
投稿日時: 2007-05-31 01:22
> かるあ さん

データが欠落する、ということについて補足します。

例えば、データベース内に 30 KB の画像と 500 KB の画像が
入っていたとして、それがランダムに 1000 レコードあるとします。

そして、そのテーブルを全件読み込むプログラムを、
ODP.NET を使って組んで実行します。
すると、OracleDataReader の GetBytes の値が、
いくら 500 KB の画像を読み込んだとしても、500 KB 未満で
GetBytes() が終わってしまうポイントが現れます。
もしくは、30 KB のデータを読み込もうとしたけど、
30 KB 未満で途切れてしまう、というポイントも現れます。
GetBytes() については、これ以上読み込めない、という
ところまでループで読み込んでいますので、コーディング自体、
特殊なことをやってるわけではありません。
しかも、ステップ実行で動かしてみても、明らかにバッファの
サイズよりも小さいサイズのデータが入ってきていることが確認されてます。


参考サイトにもあるように、ほとんど同一サイズのデータじゃないと
ダメなのか、と思って色々とサンプルを書いてみたんですが、
どうやら、最も小さなサイズのデータに基準を置いてプロパティを設定
しないといけない、ということがわかってきました。
つまり、30 KB のデータに基準をあわせ、500 KB のデータは、30 KB の
バッファにチャンクする、という方法をとることで一応は問題解決できました。
ですが、やはり納得できない感じがします。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2007-05-31 08:07
引用:

ケビンさんの書き込み (2007-05-31 01:22) より:

つまり、30 KB のデータに基準をあわせ、500 KB のデータは、30 KB の
バッファにチャンクする、という方法をとることで一応は問題解決できました。
ですが、やはり納得できない感じがします。


なるほど。。。参考になります。(というか参考にならずにすみません(汗)
ちょっとした興味なんですが、この場合 GetBytes で取得するのと GetOracleBinary で読むのとどっちが高速なんでしょう。
_________________
かるあ のメモスニペット
ケビン
会議室デビュー日: 2007/04/12
投稿数: 15
投稿日時: 2007-06-01 01:57
> かるあ さん

GetBytes() で取得する方法と、GetOracleBinary() で取得する方法ですが、
どちらが高速か、ということですと、実際に試されるのが先決でしょう。
実際、私が実測してみたのですがミリ秒単位で GetOracleBinary() のほうが
遅い、という結果が得られましたが、これはあまり参考になる数字ではない
と思います。マシンの状態などでミリ秒単位の値は変化しますからね。

むしろ、クラスのオブジェクトを返す GetOracleBlob() を使うパターンの
ほうが明らかに遅く感じました。
実際の時間も数秒単位で遅いデータが出ました。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2007-06-01 07:51
引用:

ケビンさんの書き込み (2007-06-01 01:57) より:

GetBytes() で取得する方法と、GetOracleBinary() で取得する方法ですが、
どちらが高速か、ということですと、実際に試されるのが先決でしょう。
実際、私が実測してみたのですがミリ秒単位で GetOracleBinary() のほうが
遅い、という結果が得られましたが、これはあまり参考になる数字ではない
と思います。マシンの状態などでミリ秒単位の値は変化しますからね。


すいません、Oracle をいじれる環境が近くになかったので、単純な興味で聞いてしまいました。
なるほど、読み込むサイズを小さいほうに固定したらそれほど変わらなかったということですね。

引用:

ケビンさんの書き込み (2007-06-01 01:57) より:

実際、私が実測してみたのですがミリ秒単位で GetOracleBinary() のほうが
遅い、という結果が得られましたが、これはあまり参考になる数字ではない
と思います。マシンの状態などでミリ秒単位の値は変化しますからね。


GetBytes で一度に読み込むサイズを小さくとらないとだめで、パフォーマンスが下がってしまうなら、GetBytes よりも使いやすい GetOracleBinary でコーディングしたらどうかなと思ったまでです。
_________________
かるあ のメモスニペット
ケビン
会議室デビュー日: 2007/04/12
投稿数: 15
投稿日時: 2007-06-05 07:03
> かるあさん

LOB データの取得方法ですが、高速なアクセス方法について、
発見することができました。

GetBytes() でチャンクする方法が該当しますが、
ODP.NET のLOB データのフェッチサイズを、
-1 に設定し、チャンクをすることによってハイパフォーマンスを
発揮できました。
1

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