实体框架4.0批量操作的性能

时间:2012-11-10 12:49:42

标签: c# sql entity-framework-4

我目前正在改进使用实体框架(并且具有4.0版本)的现有c#项目的性能。 在应用程序中完成了两种类型的批量操作:

  1. 批量插入
  2. 批量删除
  3. 目前它们是使用纯SQL语句完成的(“INSERT INTO ...”,“DELETE FROM ...”) (insert语句本身当前没有批量插入语句,而是一个“普通”插入语句)。

    由于我对C#很陌生,我的第一步是研究如果我使用实体框架进行更新和删除,性能如何。

    我的问题是三折:

    1. 如果我尝试使用实体框架进行批量插入,它确实使用插入的每个数据行使用1个插入吗? (因此每个插入物的往返)。因此,性能低于使用SQL“插入”?
    2. 这对删除语句也适用吗?
    3. 这里的最佳做法是什么?要使用SQL语句?或者完全使用实体框架或其他东西?
    4. (对于数据行,我说的是每个2k-200k的大小)。

      由于

2 个答案:

答案 0 :(得分:2)

我的问题是三折:

  

如果我尝试使用实体框架进行批量插入,那是真的吗?   它是否每插入一个数据行使用1个插入? (因此往返   每个插入)。因此,性能低于使用SQL   “插入”?

是。如果要使用EF,请将以下属性设置为false以获得更快的性能:

MyContext.Configuration.AutoDetectChangesEnabled = false;
MyContext.Configuration.ValidateOnSaveEnabled = false;
  

这对删除语句也适用吗?

是。您还可以在数据库在删除级联上定义,然后数据库将删除引用的实体,因此不需要使用EF执行此操作。

  

这里的最佳做法是什么?要使用SQL语句?或者使用   实体框架,还是完全不同的东西?

您可以使用存储过程,在您的上下文中调用Query

MyContext.ExecuteStoreQuery("your query")

MyContext.Database.SqlCommand("your query"); 

另一种方法是在批处理之后调用SaveChanges()(100,200个实体标记为已添加或已删除),然后处置上下文,以便实体仍未连接。然后创建一个新的上下文制作批处理并再次调用SaveChanges()

<强>更新

我没有使用这种方法,但你可以尝试一下。

SqlBulkCopy for Generic List (useful for Entity Framework & NHibernate)

  

下面的可重复使用的通用版本,它在2.4秒或更短时间内产生了15k插入物   + - 每秒6200行。我把它增加到4个目录,3939个224392行,+ - 5750 rps(在4个文件之间更改)。

答案 1 :(得分:2)

如果您确实想要插入批量数据,则可能需要使用SqlBulkCopy。您可以在EF上下文使用的同一事务中使用它。

EF不适用于批量操作,您可能会发现其单行每语句DML方法对大型集合来说过于严格。它会强制进行大量的往返,大量的每语句开销,并阻止SQL Server同时优化多行的查询计划,这几乎总是比许多小查询更有效(例如,SQL Server将对所有行进行正确排序,以便索引可以按顺序更新。

通过使用EF来执行批量DML,您基本上强制SQL Server使用每行DML计划。

可以通过将密钥大量插入临时表,然后执行连接到该表的删除语句来处理批量删除。