使用SQL Server CE 4.0和Entity Framework 4.2的批量插入的性能非常差

时间:2012-01-23 23:35:48

标签: .net performance entity-framework sql-server-ce-4

我使用Entity Framework 4.2(代码优先)将大量数据插入到SQL Server CE 4.0中,与直接SQL插入相比,性能极差。

模型非常简单:

public class DocMember
{
    public DocMember() { this.Items = new List<DocItem>(); }

    public int Id { get; set; }

    public string Name { get; set; }
    public string MemberType { get; set; }
    public string AssemblyName { get; set; }

    public virtual IList<DocItem> Items { get; set; }
}

public class DocItem
{
    public int Id { get; set; }
    public DocMember Member { get; set; }
    public string PartType { get; set; }
    public string PartName { get; set; }
    public string Text { get; set; }
}

我要插入2623 DocMembers和总共7747 DocItems,我将获得以下执行时间:

With SQL: 00:00:02.8
With EF:  00:03:02.2

我可以理解EF有一些开销,但它比SQL慢<65> !

也许我的代码中存在问题,但它非常简单,我看不出有什么问题:

    private TimeSpan ImportMembersEF(IList<DocMember> members)
    {
        using (var db = new DocEntities())
        {
            db.Database.CreateIfNotExists();

            var sw = Stopwatch.StartNew();
            foreach (var m in members)
            {
                db.Members.Add(m);
            }

            db.SaveChanges();
            sw.Stop();
            return sw.Elapsed;
        }
    }

我还尝试为每个插入的项目或每100或200个项目调用SaveChanges无效(实际上会使情况变得更糟)。

有没有办法提高性能,还是我必须使用SQL进行批量插入?


编辑:为了完整性,这是SQL插入的代码:http://pastebin.com/aeaC1KcB

2 个答案:

答案 0 :(得分:6)

您可以使用我的SqlCeBulkCopy库来加载批量数据,它模仿SqlBulkCopy api:http://sqlcebulkcopy.codeplex.com

答案 1 :(得分:1)

它很慢,因为它没有对插入物进行批处理。

在db上使用identity插入时,必须在每个项目之后选择结果ID以分配给模型。这使得它真的很慢。

您的adhoc SQL没有选择ID,因此在批处理时您可以一次提交所有语句。

Altho用NHibernate写的:

http://www.philliphaydon.com/2011/09/the-benefits-of-letting-the-orm-generate-the-identity-part-1/

我写了关于使用ORM生成的ID与SQL生成的ID的文章。