web-dev-qa-db-ja.com

EF 4.1にエンティティを挿入するのは、ObjectContextと比較して非常に遅いのはなぜですか?

基本的に、1つのトランザクション内に35000個のオブジェクトを挿入します。

using(var uow = new MyContext()){
  for(int i = 1; i < 35000; i++) {
     var o = new MyObject()...;
     uow.MySet.Add(o);
  }
  uow.SaveChanges();
}

これは永遠にかかります!基になるObjectContextを(IObjectAdapterを使用して)使用すると、まだ遅いですが、約20秒かかります。 DbSet<>は線形検索を行っていますが、これには時間がかかります...

この問題を見ている人はいますか?

79
Hartmut

コメントでLadislavが既に示したように、パフォーマンスを改善するには自動変更検出を無効にする必要があります。

context.Configuration.AutoDetectChangesEnabled = false;

この変更検出は、DbContext AP​​Iでデフォルトで有効になっています。

DbContextObjectContext AP​​Iと非常に異なる動作をする理由は、DbContext AP​​Iの多くの関数がDetectChangesの関数よりもObjectContextを内部的に呼び出すためです。 $ var] _自動変更検出が有効な場合のAPI。

ここ デフォルトでDetectChangesを呼び出す関数のリストを見つけることができます。彼らです:

  • AddAttachFindLocalRemove、またはDbSetメンバー
  • GetValidationErrorsEntrySaveChanges、またはDbContextメンバー
  • EntriesDbChangeTrackerメソッド

特に、AddDetectChangesを呼び出します。これは、パフォーマンスの低下の原因となります。

これとは対照的に、ObjectContext AP​​IはDetectChangesでのみ自動的にSaveChangesを呼び出しますが、AddObjectおよび上記の他の対応するメソッドでは呼び出しません。これが、ObjectContextdefaultパフォーマンスが速い理由です。

なぜ多くの関数でDbContextにこのデフォルトの自動変更検出を導入したのですか?確かではありませんが、それを無効にして適切なポイントでDetectChangesを手動で呼び出すことは 高度であり、アプリケーションに微妙なバグを簡単に導入できるため、注意して[it]を使用できます =。

124
Slauma

EF 4.3 CodeFirstを使用した小さな経験的テスト:

AutoDetectChanges = trueで1000オブジェクトを削除:23秒

AutoDetectChanges = false:11秒で1000個のオブジェクトを削除しました

AutoDetectChanges = trueで1000オブジェクトを挿入:21秒

AutoDetectChanges = falseで1000オブジェクトを挿入:13秒

11
Zax

.netcore 2.0では、これは次の場所に移動されました。

context.ChangeTracker.AutoDetectChangesEnabled = false;

4
Maxvt

あなたがここで見つけた答えに加えて。データベースレベルでは、追加するよりも挿入する方が作業が多いことを知っておくことが重要です。データベースは、新しいスペースを拡張/割り当てる必要があります。次に、少なくとも主キーインデックスを更新する必要があります。更新時にインデックスも更新される場合がありますが、あまり一般的ではありません。外部キーがある場合は、それらのインデックスも読み取って、参照整合性が維持されていることを確認する必要があります。トリガーも役割を果たすことができますが、それらは更新に同じように影響を与える可能性があります。

データベースのすべての作業は、ユーザーエントリによって発生する毎日の挿入アクティビティで意味があります。ただし、既存のデータベースをアップロードするだけの場合、または大量の挿入を生成するプロセスがある場合。あなたはそれを最後まで延期することによって、それをスピードアップする方法を見たいと思うかもしれません。通常、挿入中にインデックスを無効にすることが一般的な方法です。場合に応じて実行できる非常に複雑な最適化があり、それらは少し圧倒される場合があります。

一般的に、挿入は更新よりも時間がかかることを知っておいてください。

1