オブジェクト/エンティティに逆シリアル化するサービス(return xml)からデータをプルするプロジェクトがあります。
私はEFCFを使用しており、データが大きくなりすぎず、15万レコードしかないまでテストは正常に機能しています。SQLプロファイルを使用してSQLステートメントをチェックしていますが、非常に高速ですが、非常に遅い問題があります。挿入ステートメントを生成しています。
簡単に言えば、データモデルは単純で、クラスClientには多くの子オブジェクトセット(5)と1つの多対多の関係があります。
モデルのIDはサービスから提供されるため、1つのエンティティの重複するインスタンスをクリーンアップしました(同じID)。
var clientList = service.GetAllClients(); // return IEnumerable<Client> // return 10K clients
var filteredList = Client.RemoveDuplicateInstancesSameEntity(clientList); // return IEnumerable<Client>
int cur = 0;
in batch = 100;
while (true)
{
logger.Trace("POINT A : get next batch");
var importSegment = filteredList.Skip(cur).Take(batch).OrderBy(x=> x.Id);
if (!importSegment.Any())
Break;
logger.Trace("POINT B: Saving to DB");
importSegment.ForEach(c => repository.addClient(c));
logger.Trace("POINT C: calling persist");
repository.persist();
cur = cur + batch;
}
ロジックは単純で、プロセスをスピードアップするためにバッチに分割します。100個のクライアントごとに約1000個の挿入ステートメントが作成されます(子レコードと1つの多対多のテーブルの場合)。
プロファイラーとロギングを使用してこれを分析します。挿入直後
ログには、常に最後のステップとしてポイントBが表示されます。しかし、プロファイラーにはまだ挿入ステートメントがありません。2分後、すべての挿入ステートメントが表示され、次のバッチのポイントBが表示されます。そしてまた2分。
私は何か間違ったことをしましたか、それとも改善するために設定や何かできることがありますか?
1kレコードの挿入は速いようです。プロセスの開始時にデータベースが消去されるため、そこにレコードはありません。SQLの速度が遅いという問題ではないようですが、EFが挿入ステートメントを生成していますか?
プロジェクトは機能しますが、遅いです。私はそれをスピードアップし、データの大きなチャンクに関してはEFについてもっと理解したいと思います。またはこれは正常ですか?
最初の100は速く、それからどんどん遅くなっていきます。ポイントBの問題のようです。データが多すぎると、repo / dbcontextがタイムリーに処理できない問題ですか?
repoはdbcoontextからの継承であり、addClientは単純です
dbcontext.Client.Add(client)
どうもありがとうございます。