【发布时间】:2017-05-18 13:18:15
【问题描述】:
我注意到我的后台作业在每批之后表现更差。基本上,作业需要巨大的 csv 文件,然后以 250 条记录为单位更新数据库中的相关记录。在每批之后,我都会重新创建数据库上下文以保持 ObjectContext 整洁,但这无济于事,而且看起来每批之后一切都变得越来越慢。我的工作是:
- 从文件中读取 250 条记录
- 创建 DbContext
- 然后对于每条记录
- 从数据库中获取对应的实体
- 更新属性(反射)
- 处理 250 条记录时 - SaveChanges
因此,当作业开始时,4. 大约需要 170 毫秒,5 需要大约 6 毫秒。
50个批次后,4个需要~430ms,5个需要~500ms。
有人可以解释一下这里发生了什么吗?
更新。 事实证明,这不是hangfire 故障 - 所以我删除了所有对hangfire 的引用。
问题似乎出在 DbContext 上,尽管我正在重新创建 DbContext 处理在每批之后仍然需要更长的时间。我也错过了 5 的一件事。 - 每次都需要更长的时间打电话给dbContext.Entry(entity).Property("Guid").IsModified = false:
//for each 250 items
var dbContext = new MyDbContext();
dbContext.Configuration.ValidateOnSaveEnabled = false;
foreach (var item in items)
{
var entity = dbContext.MyItems
.Include(x => x.SomeProp) // lots of these
.FirstOrDefault(BuildFilterFrom(item)); //after each batch this taking longer (starting from 170ms and then after 50 batches it takes 430ms)
//set entity propties from item
//...
dbContext.Entry(entity).Property("Guid").IsModified = false //after each batch this also taking longer (starting from 6ms and then after 50 batches it takes 500ms)
}
dbContext.SaveChanges();
【问题讨论】:
-
你能提供执行这六个步骤的代码片段吗?
-
检查此进程生成的 SQL 脚本。我最近遇到了类似的情况,Entity Framework 创建了可怕的 SQL(实际上并不是它的错),并且因为我多次执行它,它正在炸毁查询优化器。由于您没有进行批量抓取,这减少了我的场景应用的机会,但我仍然会查看数据库连接。
-
运行时系统资源是什么样的(潜在的内存泄漏)?
-
@Nico 我用更多细节更新了我的问题。
-
@krillgar 感谢您的评论,我认为您可能是对的 - db 调用一定有问题..
标签: c# performance entity-framework batch-processing