私は、c# と Fluent NHibernate で構築されたプロジェクトで、さまざまな大規模なデータ変更操作を行っています。DBはsqliteです(パフォーマンスに関心があるため、メモリではなくディスク上にあります)
これらのパフォーマンスをチェックしたかったので、大量のデータをフィードしてプロセスに処理をさせるテストをいくつか作成しました。これらのプロセスのうちの 2 つの結果は、私をかなり混乱させました。
1 つ目は、XML ファイルで提供されたデータを取得し、簡単な処理を行ってインポートする、かなり単純なケースです。XML には約 172,000 行が含まれており、プロセスの実行には合計で約 60 秒かかり、実際の挿入には約 40 秒かかります。
次のプロセスでは、同じデータ セットに対して何らかの処理を行います。したがって、1 つのテーブルに約 172,000 行の DB があります。次に、プロセスはこのデータを処理し、より重い処理を行い、一連の DB 更新 (同じテーブルへの挿入と更新) を生成します。合計すると、約 50,000 行が挿入され、80,000 行が更新されます。この場合、処理には約 30 秒かかりますが、DB への変更の保存には 30 分以上かかります。そして、sqlite 'disk or i/o error' で終了する前にクラッシュします
問題は、2 番目のプロセスでの挿入/更新が非常に遅いのはなぜですか? 彼らは同じ接続で同じデータベースの同じテーブルで作業しています。どちらの場合も、IStatelessSession が使用され、ado.batch_size は 1000 に設定されています。
どちらの場合も、コードは次のように更新されます。
BulkDataInsert((IStatelessSession session) =>
{
foreach (Transaction t in transToInsert) { session.Insert(t); }
foreach (Transaction t in transToUpdate) { session.Update(t); }
});
(ただし、最初のプロセスには挿入のみであるため、'transToUpdate' 行はありません。更新行を削除して挿入を行うだけでも、まだ約 10 分かかります。) transTo* 変数は、更新/挿入するオブジェクトを含むリストです。
BulkDataInsert はセッションを作成し、DB トランザクションを処理します。