- - PR -
ODP.NET での LOB データ取得について
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 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 ] | ||||||||
|
投稿日時: 2007-05-30 23:19
データが欠落するということは一度の GetBytes メソッドでは読み込み切れなかったということではないでしょうか?
GetBytes メソッドの返却値は 読み込んだバイト数なので、期待したバイト数に達していなかったらもう一度 GetBytes する必要があると思います。 _________________ かるあ のメモ と スニペット | ||||||||
|
投稿日時: 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 の バッファにチャンクする、という方法をとることで一応は問題解決できました。 ですが、やはり納得できない感じがします。 | ||||||||
|
投稿日時: 2007-05-31 08:07
なるほど。。。参考になります。(というか参考にならずにすみません(汗) ちょっとした興味なんですが、この場合 GetBytes で取得するのと GetOracleBinary で読むのとどっちが高速なんでしょう。 _________________ かるあ のメモ と スニペット | ||||||||
|
投稿日時: 2007-06-01 01:57
> かるあ さん
GetBytes() で取得する方法と、GetOracleBinary() で取得する方法ですが、 どちらが高速か、ということですと、実際に試されるのが先決でしょう。 実際、私が実測してみたのですがミリ秒単位で GetOracleBinary() のほうが 遅い、という結果が得られましたが、これはあまり参考になる数字ではない と思います。マシンの状態などでミリ秒単位の値は変化しますからね。 むしろ、クラスのオブジェクトを返す GetOracleBlob() を使うパターンの ほうが明らかに遅く感じました。 実際の時間も数秒単位で遅いデータが出ました。 | ||||||||
|
投稿日時: 2007-06-01 07:51
すいません、Oracle をいじれる環境が近くになかったので、単純な興味で聞いてしまいました。 なるほど、読み込むサイズを小さいほうに固定したらそれほど変わらなかったということですね。
GetBytes で一度に読み込むサイズを小さくとらないとだめで、パフォーマンスが下がってしまうなら、GetBytes よりも使いやすい GetOracleBinary でコーディングしたらどうかなと思ったまでです。 _________________ かるあ のメモ と スニペット | ||||||||
|
投稿日時: 2007-06-05 07:03
> かるあさん
LOB データの取得方法ですが、高速なアクセス方法について、 発見することができました。 GetBytes() でチャンクする方法が該当しますが、 ODP.NET のLOB データのフェッチサイズを、 -1 に設定し、チャンクをすることによってハイパフォーマンスを 発揮できました。 |
1