0
私は約900K行のデータをインポートし、それを新しいデータモデルにマップしようとしています。 私の問題は、このインポート機能用にビルドしたコンソールアプリケーションが時間の経過とともに減速することです。コンソールアプリケーションが時間の経過とともに減速する
私はSQLクエリを監視しており、すべてが正常に実行されています(< 5ms)。 一度に小さなチャンク、fx 1K行をインポートしようとしました。 ストップウオッチのタイミングは次のようになります。
- Count:100 |平均時間:36
- 数:200 |平均時間:67
- 数:300 |平均時間:106
- 数:400 |平均時間:145
- 数:500 |平均時間:183
- 数:600 |平均時間:222
- 数:700 |平均時間:258
- 数:800 |平均時間:299
- 数:900 |平均時間:344
- 数:1000 |平均値:376
新しい1K行のチャンクでアプリケーションを再起動すると、タイミングが似ています。
インポートデータの形式は次のとおりです。
public class ImportData
{
public int Id { get; set; }
public int TaxpayerId { get; set; }
public string CustomerName { get; set; }
public string Email { get; set; }
public string PhoneNumber { get;set; }
}
私のデータモデルの単純化した例は次のようになります。
public void Import()
{
Stopwatch stopwatch = new Stopwatch();
//Get import data
List<ImportData> importDataList = _dal.GetImportData();
stopwatch.Start();
for (int i = 0; i < importDataList.Count; i++)
{
ImportData importData = importDataList[i];
Taxpayer taxpayer = new Taxpayer()
{
Name = importData.CustomerName,
TaxpayerId = importData.TaxpayerId,
Permissions = new List<Permission>()
};
//Does not call SaveChanges on the context
CreateTaxpayer(taxpayer, false);
//Create permissions
if (!string.IsNullOrWhiteSpace(importData.Email))
{
//Does not call SaveChanges on the context
CreatePermission(_channelIdEmail, importData.Email, taxpayer, PermissionLogType.PermissionRequestAccepted);
}
if (!string.IsNullOrWhiteSpace(importData.PhoneNumber))
{
//Does not call SaveChanges on the context
CreatePermission(_channelIdPhoneCall, importData.PhoneNumber, taxpayer, PermissionLogType.PermissionRequestAccepted);
//Does not call SaveChanges on the context
CreatePermission(_channelIdSms, importData.PhoneNumber, taxpayer, PermissionLogType.PermissionRequestAccepted);
}
if ((i + 1) % 100 == 0)
{
Console.WriteLine("Count: " + (i + 1) + " | Avg ms: " + stopwatch.ElapsedMilliseconds/100);
stopwatch.Restart();
}
}
_dal.SaveChanges();
}
:
public class Channel
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Permission
{
public Guid Id { get; set; }
public Channel Channel { get; set; }
public string Recipient { get; set; }
}
public class Taxpayer
{
public Guid Id { get; set; }
public int TaxpayerId { get; set; }
public string Name { get; set; }
public List<Permission> Permissions { get; set; }
}
私のインポート方法は次のようになります
私は以下を試しました:
- (運なし)マルチスレッド実装
- (唯一の終わりに一度と呼ばれる)のSaveChangesへの呼び出しの数を減らすこと - 私は、エンティティフレームワーク
と手をつないで行くようには見えませんここでアイディアが不足しています。このパフォーマンスの問題を解決するための提案はありますか?
を[MCVE]を作成してください。表示するコードには明らかな問題はありません。私はあなたがコレクションにアイテムを追加するにつれ、徐々に遅くなるLinq(エンティティまたはオブジェクトのいずれか)クエリをどこかで行うと思われます。 – CodeCaster
* ORMは使用しないでください。 SqlBulkCopyを使用します。 ORMはバッチ操作のためのものではなく、ピンセットを使って岩石のトラックを移動させるのと同じです。 *すべての*レコードを追跡して、*挿入ごとに個別のINSERT要求を送信します。変更トラッキングを無効にしたり、EFにバッチ処理を追加して複数の要求をまとめて送信する拡張機能を追加することもできますが、SqlBulkCopyでEFを使用しても何も得られません。 –
[SqlBulkCopyとEntity Framework]の可能な複製(http://stackoverflow.com/questions/2553545/sqlbulkcopy-and-entity-framework) –