BLOBやCLOBのパフォーマンスを改善したい

このQ&Aのポイント
  • Oracle 10g R2 を使用し、開発を行っていますが、パフォーマンス改善という壁にぶつかっております。要求定義の段階で、可変長のバイナリデータを扱う必要があり、テーブル内には BLOB フィールドを用意しております。
  • 現状としてプログラムの中でボトルネックとなっているのは、BLOB データを Fetch するタイミングなんです。開発環境は、C#.NET+ODP.NET なんですけど、ミドルウェアは、oo4o を使った場合でも、Microsoft の Oracle のドライバを使用したときでも同じ部分でボトルネックになっていました。
  • そもそも、この BLOB フィールドや CLOB フィールドのデータを Fetch する速度を向上させること、というのは可能なのでしょうか?ちなみに、Oracle サーバ側の設定は一切行っておりません。
回答を見る
  • ベストアンサー

BLOBやCLOBのパフォーマンスを改善したい

Oracle 10g R2 を使用し、開発を行っていますが、 パフォーマンス改善という壁にぶつかっており、 お助けいただきたいと思いました。 要求定義の段階で、可変長のバイナリデータを扱う必要があり、 テーブル内には BLOB フィールドを用意しております。 レコード件数にすると、全体でおおよそ 500,000 ~ 1,000,000 件に なります。(導入先によって上記範囲内で変動する) データはさらに区分によって判別されるようになっております。 プログラムから投入する SQL 文については、 最適化を行っておりまして、最高のパフォーマンスが得られる であろう構文になっておりますし、テーブルの設計についても、 検索条件となる項目へのインデックス設定を行っています。 現状としてプログラムの中でボトルネックとなっているのは、 BLOB データを Fetch するタイミングなんです。 開発環境は、C#.NET+ODP.NET なんですけど、ミドルウェアは、 oo4o を使った場合でも、Microsoft の Oracle のドライバを 使用したときでも同じ部分でボトルネックになっていました。 ちなみに、BLOB をやめて、CLOB にした場合も、 CLOB データを Fetch する部分がボトルネックになっていました。 テスト段階なのでバイナリデータが 4 KB 未満ですが、 これを VARCHAR2(4000) のフィールドに Base64文字列などで 格納した場合は、LOB データの Fetch はありませんので、 かなり高速な処理が実現できるのですが、実際の運用では、 4 KB を超えるようなバイナリデータが普通に現れてきます。 なので、VARCHAR2 でのデータベース設計ができない状態です。 そもそも、この BLOB フィールドや CLOB フィールドのデータを Fetch する速度を向上させること、というのは可能なのでしょうか? ちなみに、Oracle サーバ側の設定は一切行っておりません。

  • Oracle
  • 回答数3
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • MZ-80B
  • ベストアンサー率56% (46/81)
回答No.3

1冊のマニュアルになるボリュームがあって色々書かれているので 開発者ガイドを見てください。 「アプリケーション開発者ガイド- ラージ・オブジェクト」です 個人的には設計段階でLOBは使用しないように最大限粘っていると思います。

参考URL:
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19247-01/toc.htm
SUPER-NEO
質問者

お礼

> MZ-80B さん OTNのドキュメント、拝見しました。 LOB は使わない、ということですか。 格納するデータに制限をつければ確かに遅い LOB を使わずに、 高速なカーソル操作が実現できそうですね。 ちょっと設計を見直してみることにします。

その他の回答 (2)

  • MZ-80B
  • ベストアンサー率56% (46/81)
回答No.2

下位互換といわれているのは LONG RAW の事ではないでしょうか。 RAW はこれからも残っていくデータ型だったと思います。 RAW型の最大サイズは2000バイトなのでBASE64のVARCHAR2(4000)と比べると 1カラムでの容量では負けてしまいますね。

SUPER-NEO
質問者

お礼

> MZ-80B さん 度々回答していただき、ありがとうございます。 RAW 型について勘違いをしておりました。 大変、申し訳ございませんでした。 今の開発環境が、.NET Framework である、ということもあって、 GZIP による圧縮を仮に想定したとして、どれだけ圧縮されるのか、 これを十分に考慮してテーブル設計をやりなおさなければ、と思います。 今のところ、登録するバイナリデータの制限が無いことがあり、 RAW フィールドを、いくつテーブルに用意すればよいのか、 という点での問題が残ります。 もしかするとRAWフィールドを設ける方法が使えない、という場合も考えられます。 提供いただいた参考サイトを拝見しますと、そもそも Oracle という データベースにおいて BLOB のアクセスが遅い、というような表現が 見受けられましたが、やはり BLOB というものを MySQL 並みとは言わなくても、それに近づけるような速くする チューニングテクニックというのは存在しないものなのでしょうか。 Oracle の製品で提供されている機能なんかを見てみると、 BLOB で出力しているパッケージ・ファンクションなんかが見つかります。 BLOB が遅いということになると、こういった関数の部分のパフォーマンスも 大きく劣ってしまう、ということだと思うんです。

  • MZ-80B
  • ベストアンサー率56% (46/81)
回答No.1

LOBのデータサイズによってパフォーマンスは変わるので ひとつの例として参考にしてください。 小さなLOBについて検証しているケースなので似た状況かも。 あとバイナリを扱うなら文字にエンコードするとサイズが倍増しますから RAW型を使ったほうがよいです。

参考URL:
http://www.drk7.jp/MT/archives/001196.html
SUPER-NEO
質問者

お礼

> MZ-80B さん 回答ありがとうございます。 バイナリデータの圧縮、気づきませんでした! 確かにデータが小さければ小さいほど読み込むデータ量も 小さくできるので快適になることが期待されますね。 試してみます。 あと、確認なんですが、RAW型を使ったほうが良い、 ということが回答中にありますが、何故 RAW 型とされたのでしょうか? OTNのドキュメントを拝見しておりますと、Oracle 10g では、 下位互換のために用意されている型とあります。 そういうわけで、RAW 型ではなく LOB 型を使ってほしい、 ということが書かれています。 RAW 型の変わりに LOB 型を使っても良いものなのでしょうか?

関連するQ&A

  • Oracle : BLOB型フィールドへのデータ設定方法

    Oracle9iで、 あるテーブルのBLOB型フィールドへバイナリーデータを設定する方法をご教授ください。 とにかく、一回だけ、 ある1レコード(あるいは全レコード同じデータでもかまわない)の1フィールドに何かを設定できればいいので ・オペレーション(手入力)で設定 ・設定するプログラムを作る いずれでも構いません。 利用できるのは ・オブジェクトブラウザ ・Oracle9i標準のツール(sqlplus等) 作成可能なプログラム ・VC++ , VB よろしくお願いします

  • バイナリデータをOracleテーブルに登録したい。

    VB6.0、Oracle9iを使用して、バイナリデータを登録・参照するプログラムを作ろうとしています。 やりたいことは以下の通りです。 1.OracleのBLOB形のフィールドにバイナリデータ(bmp,xlsなど)を登録する。 2.1で登録したバイナリデータを取得し、テンポラリフォルダに保存する。 どなたがご存知の方がいらっしゃいましたら教えて下さい。 宜しく御願いします

  • CLOBデータの取得方法

    実行環境は、WindowsXP,VB6(SP6),Oracle10gで、oradc.ocxを使ってoo4接続しています。 SELECT実行時は、ORA_DYNASET.Fieldsを参照して.VALUEから検索結果値を取得しています。 今まで、LONG型フィールドは何もせずに値の取得が可能でしたが、 CLOB型に変更したことにより、ここでエラーが発生するようになりました。 CLOBのフィールドにto_char関数をかけると、.VALUE参照時のエラーは無くなりましたが、データが4000バイトで切れてしまいます。 現在当方での唯一の回避策は、CLOB型フィールド名を"A"とすると、 to_char(substr(A,1,4000)), to_char(substr(A,4001,4000)), to_char(substr(A,8001,4000)) ・・・・・ といった形でのSELECT文をきる事になります。 そもそもは、.VALUEプロパティ参照時のエラーを無くしたいのですが、無くす方法、又は、それにみあう代替策をご存知の方は教えてください。 ※なお、LONG型の場合も、10gになってからはデータが4000バイトで切れるとの報告も受けております。最初はTO_CHAR関数のせいだと思っていましたが、VB側のオブジェクトの壁なのでしょうか・・・

  • getBinaryOutputStream()が使えなくて困ってます。

    OracleのBlobにバイナリデータを挿入しようとプログラムを作成中ですが、BLOBファイルへの出力ストリームを生成する際に、 blob.getBinaryOutputStream(); を使おうとしているのですが、BlobクラスのメソッドにgetBinaryOutputStream()が存在していませんでした。Java初心者でサンプルソースを実行させようとしているのですが、この問題が立ちはだかって先に進めません・・・ どなたかこの問題についてアドバイス頂けると幸いです。 開発環境は、 JDK1.4 Oracle8.1.7 です。 よろしくお願いします。

    • ベストアンサー
    • Java
  • Oracle8iのBLOBに画像を登録する方法

    お世話になります。 現在以下のテーブルに画像を取り込むことを行っているのですが、SQL/PLUS等のコマンドで登録する場合どのようなコマンドになるでしょうか? CREATE TABLE Book (No Number(2) NOT NULL, BookName Varchar2(100) NOT NULL, BookAuthor Varchar2(100) NOT NULL, Genre Number(2) NOT NULL, image BLOB, constraint pk_Books primary key(No))TABLESPACE usertsp PCTFREE 5 PCTUSED 90 STORAGE(INITIAL 10k NEXT 1k PCTINCREASE 0 MINEXTENTS 1 MAXEXTENTS UNLIMITED); BLOB型のフィールド(image)に画像を取り込む方法をご存知の方 よろしくお願いします。

  • Oracle8での数値チェック

    現在、Oracle8.1.7で開発しております。 検索する条件として、『数値かどうか』または『文字列かどうか』 という判断を行いたいのですが可能でしょうか? やりたい事は、以下のデータの右から2桁目が数値となっているものと 文字列になっているものとを区別したいのです。  ○○○○-A01  ○○○○-C99  ○○○○-AB1  ○○○○-Z21     : 設計上、すべてのフィールドは『VARCHAR2』となっています。 よろしくお願いしますm(_ _)m

  • Oracle10gをACCESSでリンクした場合の不具合

    ORACLEのデータベースをACCESSを使用してODBCで リンクを張り、テーブルの管理をしています。 環境は OLACLE 10g 10.1.0.2.0 ACCESS 2007 WinXP SP2 ODBC:Oracle in OraClient10g 10.01.00.02 OLACLEのテーブルにNVARCHAR2,CLOB型のフィールドを作成し ACCESSでリンク後に、そのフィールドにデータを入力すると 「ORA-01461:LONG値はLONG列にのみバインドできます。」 というエラーがでます。 テーブル定義は CREATE TABLE test( id NUMBER(5) PRIMARY KEY, data1 NVARCHAR2(1000), data2 CLOB ) といった感じです(実際はもっと多いですが・・・) このテーブルでdata1のフィールドに 「あああ」と入力するとエラーがでるのですが、 「aあ」と入力するとエラーはでずに、保存可能です。 「aああ」だと同じくエラー、 「aaああ」だとOK (「a」は半角) 調べたところMicrosoftのODBCはNVARCHAR2型やCLOB型には 対応していない、と言うことはわかったのですが、 ORACLEのODBCでもダメなのでしょうか・・・? UNICODEを使用するので、どうしてもNVARCHAR2が必要なのですが、 対応策をお願いします

  • JDBCのパフォーマンス

    JDBCのパフォーマンスがあがらず困っています。 LinuxマシンでOracleを稼働しており、そこにJDBCで接続しています。単一でのアクセスでは全く問題のないパフォーマンスですが、同時接続数が2以上になると途端に悪くなります。 # スレッド1→スレッド10でレスポンスに5倍の時間がかかってしまう。。。 OracleでMTS設定なども行ってみましたが、変わりませんでした。コネクションプールも行っています。 JDBCを用いてマルチスレッドでアクセスするときにボトルネックとなるポイント、チェック項目等、アドバイスをいただければ助かります。 よろしくお願いいたします。 [環境] Linux RedHat6.2J(カーネル2.2.14smp) Oracle8.1.6 JDK1.3.0 JDBCドライバ Oracleで配布しているclasses12.zip

  • BLOB列作成でORA-03001が出ます

    皆様こんにちは。 環境はcompatible = 9.0.0で作成した データベースです。 下記のSQLで表領域を作成し、その表領域を指定して BLOB列を含むテーブルを作成しようとすると、 ORA-03001:実装されていない機能ですエラー が出てしまいます。 create tablespace data_ts datafile 'd:\oracle\oradata\data\data_ts.dbf' size 256M autoextend on next 10M maxsize 1024M extent management local segment space management auto / 原因と対処法をご存知の方がおられましたら お助けください。 よろしくお願いいたします。

  • long型へのINSERTについて

    はじめましてアオツキと申します。 わたしはシステム開発を行なっていて、JAVAとOracleを使用しています。 質問させていただきたい内容は、テーブルのLONG型項目にに対してINSERT文を発行したときに起こるエラーを回避する方法です。 insert into testtable (longstr) values ('*' ×10000文字) を発行したところ「ORA-01704: 文字列リテラルが長すぎます 」 というエラーが発生しました。 このエラーを回避するため http://www.shift-the-oracle.com/oerrs/ora-01704.html 上記のURLを参考にし10000文字を分割して insert into testtable (longstr) values (TO_CLOB('*' ×3500文字) || TO_CLOB('*' ×3500文字) || TO_CLOB('*'×2000文字)) と分けてINSERT文を発行したのですが、 「ORA-22835: CLOBからCHAR、またはBLOBからRAWへの変換には、バッファーが小さすぎます(実際: 10503、最大: 4000)」 というエラーが発生しました。 このエラーについて http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19212-01/e19400.htm 上記のURLの原因と処置を呼んだのですが意味が理解できませんでした。 どなたかテーブルに長文を登録する方法をご教授いただけないでしょうか? ご回答お待ちしています。 開発環境 JAVA eclipse SQL実行 eclipseプラグイン DBViewer ORACLE 10g OJDBCドライバ ojdbc14.jar