我们有一项任务是将大约5000条记录插入到SQL表中。 最初我们通过EF,这是代码示例
foreach (var BCol in batchCollectionoutput1)
{
var context1 = new TestENTITIES.TestDbContext();
context1.Database.CommandTimeout = 6000;
context1.Configuration.AutoDetectChangesEnabled = false;
context1.Configuration.ValidateOnSaveEnabled = false;
foreach (TestENTITIES.Output1 test in BCol )
context1.Output1.Add(test);
context1.SaveChanges();
}
需要43412毫秒
之后我们想要使用SQL批量复制方法检查
using (SqlConnection sourceConnection = new SqlConnection(srcConnectionString))
{
SqlCommand myCommand1 = new SqlCommand("SELECT TOP 1000 * FROM input", sourceConnection);
sourceConnection.Open();
SqlDataReader reader1 = myCommand1.ExecuteReader();
using (SqlConnection destinationConnection = new SqlConnection(destConnectionString))
{
destinationConnection.Open();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString))
{
bulkCopy.BatchSize = 500;
bulkCopy.NotifyAfter = 1000;
bulkCopy.DestinationTableName = "Output1";
bulkCopy.WriteToServer(reader1);
}
reader1.Close();
}
}
只需要1124毫秒..
是我们在Entity框架方法中做错了吗?请指教
答案 0 :(得分:2)
不 - 你会期望EF比BulkInsert慢。
EF更适合您想要从数据库中检索数据,将结果映射到POCO,应用一些更改然后保存它们的场景。真正的好处是它与数据库无关,开发人员不必担心创建数据库连接,命令等的管道。
从导入文件或类似批量复制加载数据的位置无疑是从性能角度出发的方法。
答案 1 :(得分:0)
正如马克的评论所说,你没有进行直接比较,因为你在循环的每次迭代中都要调用SaveChanges
。
有三种方法可以做到这一点:
在自己的事务和数据库往返中运行每一行插入。很慢。
在一个事务和数据库往返中运行批处理的每一行插入。
直接批量复制。非常快。
您的EF代码正在执行1.您可以通过在循环外部移动SaveChanges
来执行2操作。你不能用EF做3,但是你不能做"只是"通常的ADO.NET机制(只有SQL命令) - 你需要一个特殊的工具(SqlBulkCopy
)。