[解決済み] Entity Frameworkにおける最速の挿入方法
質問
Entity Frameworkに挿入する最速の方法を探しています。
これを聞いているのは、アクティブな
TransactionScope
で、挿入が巨大(4000以上)である。それは潜在的に10分以上(トランザクションのデフォルトタイムアウト)続く可能性があり、これは不完全なトランザクションにつながる。
解決方法は?
質問に対するコメントへ
<ブロッククオート"...SavingChanges() 各 レコード )..."
それ、一番やっちゃいけないことですよ!?コール
SaveChanges()
は、各レコードの一括挿入を極端に遅くしています。私なら、いくつかの簡単なテストを行い、パフォーマンスを改善する可能性が非常に高いです。
-
コール
SaveChanges()
ALLレコードの後に一度だけ。 -
コール
SaveChanges()
を、例えば100レコード後に実行します。 -
コール
SaveChanges()
の後、例えば100レコードの後に、コンテキストを破棄して新しいものを作成します。 - 変更検知を無効にする
一括挿入の場合、私はこのようなパターンで作業・実験しています。
using (TransactionScope scope = new TransactionScope())
{
MyDbContext context = null;
try
{
context = new MyDbContext();
context.Configuration.AutoDetectChangesEnabled = false;
int count = 0;
foreach (var entityToInsert in someCollectionOfEntitiesToInsert)
{
++count;
context = AddToContext(context, entityToInsert, count, 100, true);
}
context.SaveChanges();
}
finally
{
if (context != null)
context.Dispose();
}
scope.Complete();
}
private MyDbContext AddToContext(MyDbContext context,
Entity entity, int count, int commitCount, bool recreateContext)
{
context.Set<Entity>().Add(entity);
if (count % commitCount == 0)
{
context.SaveChanges();
if (recreateContext)
{
context.Dispose();
context = new MyDbContext();
context.Configuration.AutoDetectChangesEnabled = false;
}
}
return context;
}
560.000のエンティティ(9つのスカラプロパティ、ナビゲーションプロパティなし)をDBに挿入するテストプログラムを持っています。このコードでは、3分未満で動作します。
パフォーマンスのために重要なのは
SaveChanges()
は、多くのレコード(100または1000程度)の後です。また、SaveChangesの後にコンテキストを破棄し、新しいものを作成することもパフォーマンスを向上させることができます。これにより、すべてのエンタイトルからコンテキストがクリアされます。
SaveChanges
ではそうならないので、エンティティはまだコンテキストにアタッチされたまま、ステート
Unchanged
. 段階的に挿入が遅くなるのは、コンテキストにアタッチされたエンティティのサイズが大きくなっているためです。そのため、しばらくしてからクリアするのが便利です。
以下は、私の560000エンティティの測定結果です。
- commitCount = 1, recreateContext = false: 何時間 (現在の手順です)
- commitCount = 100, recreateContext = falseです。 20分以上
- commitCount = 1000, recreateContext = falseです。 242秒
- commitCount = 10000, recreateContext = false: 202秒
- commitCount = 100000, recreateContext = false: 199秒
- commitCount = 1000000, recreateContext = false: メモリ不足例外
- commitCount = 1, recreateContext = true。 10分以上
- commitCount = 10, recreateContext = true。 241秒
- commitCount = 100, recreateContext = true。 164秒
- commitCount = 1000, recreateContext = true。 191秒
上記の最初のテストでの挙動は、パフォーマンスが非常に非線形で、時間とともに極端に低下することです。("Many hours" is an estimate, I never finished this test, I stopped at 50,000 entities after 20 minutes.). この非線形の挙動は、他のすべてのテストではそれほど重要ではありません。
関連
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み】OnCollisionEnter2Dが実行されない?
-
[解決済み】WebResource.axdとは何ですか?
-
[解決済み] 不変量名 'System.Data.SqlClient' を持つ ADO.NET プロバイダに対応する Entity Framework プロバイダが見つかりませんでした。
-
[解決済み] C#のオートプロパティに初期値を与える最良の方法は何ですか?
-
[解決済み] Entity Framework 5 レコードを更新する
-
[解決済み] Entity FrameworkとLINQ to SQLの比較
-
[解決済み] Entity Frameworkで生成されたSQLを表示するにはどうすればよいですか?
-
[解決済み] Entity Framework - 複数レベルのプロパティを含める
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】C#はJavaのcharAt()と同等?)
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み】MetadataException: 指定されたメタデータ・リソースをロードできない
-
[解決済み】Visual studio 2019がデバッグ時にフリーズする件
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み] 関数を終了するには?
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】スレッド終了またはアプリケーションの要求により、I/O操作が中断されました。