【问题标题】:Entity Framework much slower than ssis [duplicate]实体框架比 ssis 慢得多 [重复]
【发布时间】:2019-11-11 23:26:08
【问题描述】:

我正在尝试从包含 130 万行的表中获取所有 id,然后使用 Entity Framework 将它们插入到另一个数据库中的另一个表中。当我使用 SSIS 执行此操作时,它在 5 分钟内完成,当我使用实体框架执行此操作时,需要 3.5 小时。

我已经阅读了几个关于慢速 EF 插入的资料,它们似乎表明我应该关闭 Auto Detect Changes Enabled 并且我应该避免使用我尝试过的有循环和没有循环的循环,但这仍然需要很长时间。

我的没有循环的代码如下:

_DB2context.Configuration.AutoDetectChangesEnabled = false;
_DB2context.Table2.AddRange(_DB1context.Table1.Select(m => m.Id)
                                              .Select(pen => new Table2() { Checked = false, Id = pen }));
await _DB2context.SaveChangesAsync();

执行第三行大约需要 3.5 小时。当我尝试使用循环执行此操作时,我的代码是:

var idList = _DB1context.Table1.Select(m => m.Id).ToList();                
int i = 0;

foreach (var id in idList)
{
    i++;

    _DB2context.Table2.Add(new Table2() {Checked = false, Id = id});

    if ((i % 10000)==0)
    {
        await _DB2context.SaveChangesAsync();
    }
}

有什么明显的我做错了吗?有什么方法可以让它在运行时更像 ssis?

【问题讨论】:

  • 一般插入多少条记录?
  • 你考虑过使用SqlBulkCopy吗?
  • 130 万行。不,我没有考虑过 SqlBulkCopy,我会调查一下。
  • 我认为这是比较苹果和橘子。 SSIS 旨在执行批量操作。英孚不是。除了比较之外,还有很多关于如何改进 EF 插入行为的帖子。例如,this classic one,如果你问我,这是重复的。
  • 我认为重新创建上下文将产生巨大的影响,就像它在我链接的帖子中所做的那样。此外,您应该继续在循环中使用 AddRange。

标签: c# entity-framework ef-code-first


【解决方案1】:

Entity Framework 为每个要保存的实体执行一次数据库往返。因此,如果您有 130 万行要插入,它将导致 130 万次数据库往返,这INSANELY很慢。

正如@mjwills 已经指出的那样,您可以使用SqlBulkCopy 来获得最佳性能。


免责声明:我是Entity Framework Extensions的所有者

此库不是免费的,但允许您执行所有批量操作,包括 BulkSaveChangesBulkInsert

  • 批量保存更改
  • 批量插入
  • 批量删除
  • 批量更新
  • 批量合并

例子

// Easy to use
context.BulkSaveChanges();

// Easy to customize
context.BulkSaveChanges(bulk => bulk.BatchSize = 100);

// Perform Bulk Operations
context.BulkDelete(customers);
context.BulkInsert(customers);
context.BulkUpdate(customers);

// Customize Bulk Operations
context.BulkInsert(customers, options => {
   options => options.IncludeGraph = true;
});
context.BulkMerge(customers, options => {
   options.ColumnPrimaryKeyExpression = 
        customer => customer.Code;
});

【讨论】:

  • 我不介意在符合要求时进行一点自我宣传选择后者。希望你的产品最终成为实体框架核心产品的一部分。
猜你喜欢
  • 1970-01-01
  • 2020-12-03
  • 1970-01-01
  • 2012-09-17
  • 2018-08-20
  • 1970-01-01
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多