質問

CLOB (平均.20,000 文字)。ただし、パフォーマンスはかなり悪いようです。100 個の LOB のバッチ取得には平均して 4 秒かかります。私の観察から判断すると、この操作は I/O、CPU、またはネットワークに依存しません。

私のテスト設定は次のようになります。

PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
dataSource.setConnectionFactoryClassName("...");
dataSource.setConnectionPoolName("...");
dataSource.setURL("...");
dataSource.setUser("...");
dataSource.setPassword("...");

dataSource.setConnectionProperty("defaultRowPrefetch", "1000");
dataSource.setConnectionProperty("defaultLobPrefetchSize", "500000");

final LobHandler handler = new OracleLobHandler();
JdbcTemplate j = new JdbcTemplate(dataSource);

j.query("SELECT bigClob FROM ...",

        new RowCallbackHandler() {

            public void processRow(final ResultSet rs) throws SQLException {

                String result = handler.getClobAsString(rs, "bigClob");

            }

        });

}

フェッチサイズを試してみましたが、役に立ちませんでした。私は何か間違ったことをしているでしょうか?JDBC を使用するときに CLOB の取得を高速化する方法はありますか?

役に立ちましたか?

解決 4

すべての有益な提案をありがとう。私の答えはない良い解決策はないように思われることである問題に対する答えとしてフラグ付けされているにもかかわらず。 Iは、並列文、異なるストレージ特性、事前にソートTEMPを使用してみました。テーブルや他のもの。操作は、トレースを任意の特性目に見えるに結合した、または計画を説明することはないようです。でも、クエリの並列処理は、CLOBのが関与している時に不完全のようです。

確か11g環境が、ATMでの大のCLOB(特に圧縮)とに対処するためのより良いオプションがあるでしょう。私は10グラムで立ち往生しています。

私は、バイナリRAW最適化されたサイズにCLOBのを前処理するだろうしているデータベースへの追加の往復のために今選択しています。以前の展開で、これは常に非常に高速なオプションとなっており、おそらくオフラインで計算されたキャッシュを維持する手間価値があるだろう。キャッシュはinvalidedと誰かが良いアイデアを思い付くまで、永続的なプロセスとAQを使用して更新されます。

他のヒント

Oracle LOB タイプのデータを使用して大規模なデータを保存した私の過去の経験は、あまり良くありませんでした。varchar2 と同様にローカルに保存されるため、4k 未満の場合は問題ありません。4k を超えると、パフォーマンスの低下が見られ始めます。おそらく、数年前に最後に試して以来、状況は改善されているかもしれませんが、参考までに、私が過去に見つけたものを以下に示します。

クライアントは Oracle サーバー経由で LOB を取得する必要があるため、次の興味深い状況を考慮することができます。

  • Oracleがキャッシュすることを決定した場合、LOBデータは他のデータ型と限られたSGAキャッシュと競合します。CLOBデータが一般的に大きいため、他のデータをプッシュする可能性があります
  • LOBデータは、Oracleがキャッシュしないことを決定し、データをクライアントにストリーミングしないことを決定した場合、ディスクの読み取りが不十分です。
  • 断片化は、おそらくあなたがまだ遭遇していないものです。アプリケーションが LOB を削除し、Oracle が LOB を再利用しようとするかどうかがわかります。Oracle が LOB のディスクのオンライン デフラグをサポートしているかどうかはわかりません (インデックスにはサポートされていますが、以前に試したときは時間がかかりました)。

平均 20,000 の 100 ロブで 4 秒と述べたので、ロブごとに 40 ミリ秒になります。各 LOB は個別の Lob ロケーターを介して取得する必要があることに注意してください (デフォルトでは結果セットに含まれていません)。これは、各lobの追加のラウンドトリップであると思います(少し前のことなので100%確信はありません)。そうであれば、シリアル順序でラウンドトリップごとに少なくとも5ミリ秒の余分な時間がかかると思います、 右?その場合、パフォーマンスは、連続した LOB フェッチによってすでに制限されています。これは、SQL 実行と LOB コンテンツのフェッチに費やされた時間を追跡することで確認できるはずです。または、投稿の前の回答で示唆されているように、lob 列を除外することでこれを確認できます。これにより、lob に関連しているかどうかがわかります。

幸運を

  

結果セットの合計サイズは、10千である - 全検索のスパンで測定した初期費用

ORDER BYがクエリにありますか? 10K行、それがソートされなければならない場合には非常にたくさんある。

また、PKを取得することは、CLOB全体を取得に対して公正テストではありません。オラクル(彼らは> 4Kの場合)ブロックで、おそらく多くとテーブルの行を格納しますが、CLOBのそれぞれが一連のブロックにそれぞれ、ラインの外に保存されます。 PKのリストをスキャンするので、高速になるだろう。 Oracleはちょうどすぐにインデックスブロックをスキャンしても、テーブルにアクセスすることはできませんので、また、PKのインデックスは、おそらくあります。

4秒は少し高いようですが、それは可能ディスクからの読み出しおよびJavaプログラムをネットワーク上で転送する必要があります2MBです。ネットワークが問題である可能性があります。あなたがセッションのSQLトレースを実行する場合には、(ディスクの読み取りまたはネットワーク)の時間が費やされている場所を正確にあなたを指します。

私は同様の問題を持っていたし、LOBをaccessinときJDBC LOBがネットワーク呼び出しを行う見つけます。

は、Oracle 11.2グラムJDBCドライバのとして、あなたは、プリフェッチを使用することができます。 これは、10倍のアクセスを高速化...

statement1.setFetchSize(1000);
if (statement1 instanceof OracleStatement) {
    ((OracleStatement) statement1).setLobPrefetchSize(250000);
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top