c# - 实体框架比 ssis 慢得多
问题描述
我正在尝试从 130 万行的表中获取所有 id,然后使用 Entity Framework 将它们插入到另一个数据库中的另一个表中。当我使用 SSIS 执行此操作时,可在 5 分钟内完成,而当我使用实体框架执行此操作时,则需要 3.5 小时。
我已经阅读了几个关于慢速 EF 插入的资料,它们似乎表明我应该关闭启用自动检测更改,并且我应该避免使用我尝试过的循环和不使用循环,但这仍然需要很长时间。
我没有循环的代码如下:
_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 吗?
解决方案
Entity Framework 为每个要保存的实体执行一次数据库往返。因此,如果您有 130 万行要插入,它将造成 130 万次数据库往返,这非常慢。
正如@mjwills 已经指出的那样,您可以使用它SqlBulkCopy
来获得最佳性能。
免责声明:我是实体框架扩展的所有者
该库不是免费的,但允许您执行所有批量操作,包括BulkSaveChanges
和BulkInsert
:
- 批量保存更改
- 批量插入
- 批量删除
- 批量更新
- 批量合并
例子
// 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;
});
推荐阅读
- python - Python 3.8 请求总是返回第一页
- sql - Sybase 搜索查询
- r - 如何根据 R Shiny 中的特定输入以数字方式显示显示结果的数量?
- flutter - 如何在flutter中缓存来自firebase的图像?
- angular - 无法使用 Angular 和 RxJs 读取未定义的属性“订阅”
- performance-testing - 在 Loadrunner 中处理 .pfx 证书
- haskell - 镜头名称导致“未找到”错误,但它存在
- python - 使用 python 在 Azure TFS 中自动创建测试计划
- r - 循环问题在R中制作频率表
- spring-mvc - 从 springfox swagger 迁移到 openAPI 后,Swagger url 不起作用