基本上,我在一个事务中插入35000个对象:
using(var uow = new MyContext()){
for(int i = 1; i < 35000; i++) {
var o = new MyObject()...;
uow.MySet.Add(o);
}
uow.SaveChanges();
}
这需要永远!
如果我使用基础ObjectContex
t(使用IObjectAdapter
),它仍然很慢但需要大约20秒。看起来DbSet<>
正在进行一些线性搜索,这需要花费大量时间......
其他人都看到了这个问题?
答案 0 :(得分:124)
正如Ladislav在评论中已经指出的那样,您需要禁用自动更改检测以提高性能:
context.Configuration.AutoDetectChangesEnabled = false;
默认情况下,DbContext
API会启用此更改检测。
DbContext
与ObjectContext
API的行为如此不同的原因是DbContext
API的更多功能将在内部调用DetectChanges
而不是{{1}的函数启用自动更改检测时的API。
Here您可以找到默认调用ObjectContext
的函数列表。他们是:
DetectChanges
上的Add
,Attach
,Find
,Local
或Remove
成员DbSet
上的GetValidationErrors
,Entry
或SaveChanges
成员DbContext
Entries
方法
尤其是DbChangeTracker
来电Add
,这会导致您遇到的糟糕表现。
我将DetectChanges
API调用ObjectContext
仅与DetectChanges
中的SaveChanges
进行对比,而不是AddObject
和上面提到的其他相应方法。这就是ObjectContext
的默认效果更快的原因。
为什么他们在DbContext
这么多功能中引入了这个默认的自动更改检测?我不确定,但似乎禁用它并在适当的位置手动调用DetectChanges
被视为advanced and can easily introduce subtle bugs into your application so use [it] with care。
答案 1 :(得分:11)
使用EF 4.3 CodeFirst进行小经验测试:
使用AutoDetectChanges = true删除了1000个对象:23秒
使用AutoDetectChanges = false删除了1000个对象:11秒
使用AutoDetectChanges = true插入1000个对象:21秒
使用AutoDetectChanges = false插入1000个对象:13秒
答案 2 :(得分:4)
在.netcore 2.0中,这已移至:
<?php require('db_connect.php');
if($_POST['empid']) {
$sql = "DELETE FROM comments WHERE id='".$_POST['empid']."'";
if($sql) {
echo "Record Deleted";
}
}
?>
答案 3 :(得分:1)
除了你在这里找到的答案。重要的是要知道在数据库级别插入的工作量要多于添加的工作量。数据库必须扩展/分配新空间。然后它必须至少更新主键索引。尽管在更新时也可能会更新索引,但这种情况并不常见。如果有任何外键,它必须读取这些索引以确保保持参照完整性。触发器也可以起作用,尽管它们可以以相同的方式影响更新。
所有数据库工作在由用户条目引发的每日插入活动中都有意义。但是,如果您只是上传现有数据库,或者有一个生成大量插入的流程。您可能希望通过将其推迟到最后来寻找加速这种方法的方法。通常在插入时禁用索引是一种常见方式。根据具体情况,可以进行非常复杂的优化,它们可能有点压倒性。
只要知道插件通常需要的时间比更新时间长。