5

derby で BLOB を削除する際にパフォーマンスの問題が発生しており、誰かアドバイスを提供できるかどうか疑問に思っていました。

これは主に Windows と Solaris で 10.4.2.0 を使用した場合ですが、新しい 10.5.1.1 リリース候補 (多くの LOB の変更があるため) でもテストしましたが、大きな違いはありません。

問題は、多くの大きな BLOB を含むテーブルでは、1 つの行を削除するのに長い時間がかかる (多くの場合 1 分以上) ことです。

テーブルを作成し、サイズの異なるブロブを含むいくつかの行を挿入してから削除する小さなテストでこれを再現しました。

テーブル スキーマは単純です。

テーブル blobtest を作成します (デフォルトで ID として生成された ID 整数、b blob )

次に、1024 バイト、1Mb、10Mb、25Mb、50Mb、75Mb、100Mb のブロブ サイズで 7 行を作成しました。

ブロブが正しく作成され、正しいサイズであることを確認するために、ブロブを読み返しました。

その後、SQL ステートメントを使用して削除されています (「delete from blobtest where id = X」)。

作成した順序で行を削除すると、1 つの行を削除する平均的なタイミングは次のようになります。

1024 バイト: 19.5 秒

1Mb: 16秒

10Mb: 18秒

25Mb: 15秒

50Mb:17秒

75Mb: 10秒

100Mb:1.5秒

それらを逆の順序で削除すると、1 つの行を削除する平均タイミングは次のようになります。

100Mb:20秒

75Mb: 10秒

50Mb:4秒

25Mb:0.3秒

10Mb: 0.25秒

1Mb: 0.02秒

1024 バイト: 0.005 秒

7 つの小さなブロブを作成すると、削除時間はすべて瞬時になります。

したがって、削除時間は、削除される BLOB のサイズよりも、テーブル内の行の全体的なサイズに関連しているように見えます。

テストを数回実行しましたが、結果は再現可能のようです。

それで、誰かがパフォーマンスについて説明し、それを回避または修正する方法について何か提案はありますか? 実稼働環境で大きな BLOB を使用することは非常に問題になります…</p>

4

4 に答える 4

3

I have exact the same issue you have.

I found that when I do DELETE, derby actually "read through" the large segment file completely. I use Filemon.exe to observe how it run.

My file size it 940MB, and it takes 90s to delete just a single row.

I believe that derby store the table data in a single file inside. And some how a design/implementation bug that cause it read everything rather then do it with a proper index.

I do batch delete rather to workaround this problem. I rewrite a part of my program. It was "where id=?" in auto-commit. Then I rewrite many thing and it now "where ID IN(?,.......?)" enclosed in a transaction.

The total time reduce to 1/1000 then it before.

I suggest that you may add a column for "mark as deleted", with a schedule that do batch actual deletion.

于 2009-05-26T13:16:14.047 に答える
3

私が知る限り、Derby は BLOB を他のデータベース データとインラインで格納するだけなので、BLOB は大量の個別の DB ページ ファイルに分割されます。この BLOB ストレージ メカニズムは、ACID に適しており、小さな BLOB (画像のサムネイルなど) には適していますが、大きなオブジェクトでは機能しません。Derby のドキュメントによると、BLOB を操作するときに自動コミットをオフにするとパフォーマンスが向上する可能性がありますが、これはこれまでのところしかありません。

大規模な BLOB での優れたパフォーマンスが重要であり、BLOB を DB 内に保持する必要がある場合は、H2 または別の DBMS に移行することを強くお勧めします。SQuirrel SQL クライアントとその DBCopy プラグインを使用して、DBMS 間で直接移行できます (Derby/JavaDB JDBC ドライバーと H2 ドライバーを指すようにするだけです)。私は自分でやったばかりで、これほど満足していないので、この部分を喜んでお手伝いします.

これに失敗すると、BLOB をデータベースからファイル システムに移動できます。これを行うには、データベースの BLOB 列を BLOB サイズ (必要な場合) と場所 (URI またはプラットフォームに依存するファイル文字列) に置き換えます。新しい BLOB を作成するときは、ファイル システムに対応するファイルを作成します。場所は、主キーが追加された特定のディレクトリに基づいている可能性があります。たとえば、DB は "DBFolder/DBName" にあり、ブロブは "DBFolder/DBName/Blob" にあり、ファイル名は "BLOB_PRIMARYKEY.bin" などです。BLOB を編集または読み取るには、DB に場所を照会し、ファイルに対して直接読み取り/書き込みを行います。次に、変更された場合は、新しいファイル サイズを DB に記録します。

于 2009-05-22T15:49:06.887 に答える
1

これはあなたが望む答えではないと確信していますが、スループット要件のある実稼働環境では、Java DB を使用しません。MySQL も同様に無料で、要件をより適切に処理します。選択したソリューションの制限に対して、あなたは本当に頭を悩ませているだけだと思います。

私は通常、Derby をテスト ケースとしてのみ使用します。特に、DB 全体が簡単にメモリに収まる場合にのみ使用します。YMMV。

于 2009-05-26T19:38:31.513 に答える
0

データベースのページ サイズを増やしてみましたか?

Tuning Java DBマニュアルには、これに関する情報やその他の情報があり、役に立つと思われます。

于 2009-05-21T15:16:37.450 に答える