我正在使用Azure Sql db进行实体框架测试。 插入1条记录时,操作需要400毫秒。添加20时,它是2500毫秒。
通过EF插入1条记录的400毫秒似乎很多。EF的正常表现率是多少?
我做错了吗?
我知道批量插入可以改进,但我认为单个插入可以更快地完成!?
var start = DateTime.Now;
testdbEntities testdbEntities = new testdbEntities();
for (int i = 0; i < 20; i++)
testdbEntities.Users.Add(new User{Name = "New user"});
testdbEntities.SaveChanges();
var end = DateTime.Now;
var timeElapsed = (end - start).TotalMilliseconds;
答案 0 :(得分:2)
所有常见技巧如:
无法正常工作就像您已经注意到的那样,因为性能问题不在Entity Framework中,而是 SQL Azure
SQL Azure起初可能看起来很酷,但除非您支付了非常好的高级数据库层,否则它会很慢。
建议 Evk ,你应该尝试执行一个简单的SQL命令,如&#34; SELECT 1&#34;你会发现这可能需要超过100毫秒,这是非常慢的。
解决方案:
免责声明:我是该项目的所有者Entity Framework Extensions
另一种解决方案是使用此库,它将批量处理多个查询/批量操作。但是,即使这个库非常快,您也需要一个更好的SQL Azure层,因为它看起来每个数据库往返都需要200多天。
答案 1 :(得分:1)
每次插入都会导致提交并导致日志变硬(刷新到磁盘)。在批量写入的情况下,这可能不会导致每次插入一次刷新(直到日志缓冲区已满)。因此,尝试以某种方式批量处理结果,例如使用TVF
答案 2 :(得分:0)
您可以在插入过程中禁用自动检测更改。它确实可以提高性能。 https://msdn.microsoft.com/en-us/data/jj556205.aspx
我希望它有所帮助:)
答案 3 :(得分:0)
大多数EF应用程序都使用持久无知的POCO实体和快照更改跟踪。这意味着实体本身没有代码可以跟踪更改或通知更改的上下文。
当使用大多数POCO实体时,检测更改算法会确定实体如何更改(以及因此需要将哪些更新发送到数据库)。检测更改的工作原理是检测实体的当前属性值与查询或附加实体时存储在快照中的原始属性值之间的差异。
快照更改检测会在系统中的每个实体添加到实体框架跟踪图时获取其副本。然后,当实体更改时,将每个实体与其快照进行比较以查看任何更改。通过调用DetectChanges方法会发生这种情况。关于DetectChanges的重要信息是每次调用它时都必须通过所有被跟踪的实体,因此你在上下文中拥有的东西越多,遍历的时间就越长。
自动检测更改的作用是插入上下文中发生的事件,并且调用会在发生更改时检测到更改。
每当您添加新的用户对象时,EF都会在内部跟踪它。在其快照中保持新添加对象的当前状态。 对于批量插入操作,EF将首先将所有记录插入到DB&amp;然后调用DetectChanges函数。因此批量插入所需的执行时间是(插入所有记录所需的时间+更新EF上下文所需的时间)。
通过禁用AutoDetectChanges
,您可以相对加快数据库插入速度。所以你的代码看起来像,
using (var context = new YourContext())
{
try
{
context.Configuration.AutoDetectChangesEnabled = false;
// do your DB operations
}
finally
{
context.Configuration.AutoDetectChangesEnabled = true;
}
}