私は、デスクトップアプリケーションでエンティティフレームワークを使用してmysqlデータベースにアクセスしています。データベースは同じシステムにインストールされていますが、今ではそれを使用しているのは私だけです。DBSet.Findが遅くなり、遅くなるのはなぜですか?
特定のコレクションdocs
のオブジェクトがデータベースにすでに存在するかどうかをチェックするメソッドがあります。データベースに追加されていない場合はDBContextのsaveメソッドが最後に実行されます。メソッドは私のプログラムのループで何度も実行されます。
検索するオブジェクトの数がかなり一定(毎回約500回)であっても、このメソッドを実行するたびに検索速度が遅くなり、遅くなることに気付きました。理由は何でしょうか?
コードは、多かれ少なかれ、次のようになります。
TimeSpan timeToFind = new TimeSpan();
foreach (var docFromResult in docs)
{
DateTime operationStart = DateTime.Now;
var existingDocument =
db.VaStDocuments.Find(docFromResult.Id, docFromResult.OwnerId, docFromResult.Year);
timeToFind += DateTime.Now - operationStart;
if (existingDocument != null && docFromResult.Hash.Equals(existingDocument.Hash))
{
continue;
}
if (existingDocument == null)
{
db.VaStDocuments.Add(docFromResult);
}
else if (!docFromResult.Hash.Equals(existingDocument.Hash))
{
existingDocument.Hash = docFromResult.Hash;
existingDocument.IsNew = true;
existingDocument.Text = null;
}
docsForNotification.Add(docFromResult);
}
if (docsForNotification.Any())
{
db.SaveChangesDisplayValidationErrors();
}
だから、文書はとても基本的に、ここでの唯一のデータベース・アクティビティがFindメソッドでデータベースに記載されていないということは非常にまれなケースです。
timetoFind
一般に、は、このメソッドの実行ごとに増加します。おそらく20〜30回のループ後に120秒に達する0.5-2秒で始まる。
トラッキングされたエンティティのリストが増えているので、それを避けることができます: 'db.VaStDocuments.AsNoTracking()。Find(...)' – DavidG
@DavidG - 副作用はありますか? – Greg
このコードではパフォーマンスの向上以外は何もありません。これらのエンティティを他の場所で使用していた場合、少し苦しむかもしれませんが、私はそれを非常に疑っています。 – DavidG