为什么EF4 Code First在存储对象时如此之慢?

时间:2010-07-27 11:41:47

标签: c# entity-framework db4o

我目前正在研究如何在我的Web应用程序中使用db4o存储。我很高兴db4o的工作原理。因此,当我阅读Code First方法时,我很喜欢,因为使用EF4 Code First的方式与使用db4o非常相似:创建域对象(PO​​CO),将它们抛到db4o,永远不要回头。 / p>

但是当我进行性能比较时,EF 4的速度非常慢。我无法弄清楚原因。

我使用以下实体:

public class Recipe { private List _RecipePreparations; public int ID { get; set; } public String Name { get; set; } public String Description { get; set; } public List Tags { get; set; } public ICollection Preparations { get { return _RecipePreparations.AsReadOnly(); } }

    public void AddPreparation(RecipePreparation preparation) 
    {
        this._RecipePreparations.Add(preparation);
    }
}

public class RecipePreparation { public String Name { get; set; } public String Description { get; set; } public int Rating { get; set; } public List Steps { get; set; } public List Tags { get; set; } public int ID { get; set; } }

为了测试性能,我新建了一个配方,并添加了50.000 RecipePrepations。然后我将对象存储在db4o中,如下所示:

    public void AddPreparation(RecipePreparation preparation) 
    {
        this._RecipePreparations.Add(preparation);
    }
}

这需要大约13.000(ms)

我将这些东西与EF4存储在SQL Server 2008(Express,本地)中,如下所示:

IObjectContainer db = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), @"RecipeDB.db4o");
db.Store(recipe1);
db.Close();

这需要200.000(ms)

现在怎么样的db4o 15(!!!)快了EF4 / SQL?我错过了EF4的秘密涡轮按钮吗?我甚至认为db4o可以更快?由于我没有初始化数据库文件,我只是让它动态增长。

4 个答案:

答案 0 :(得分:3)

您是否在循环中调用了SaveChanges() ?难怪它很慢!试着这样做:

foreach(var recipe in The500000Recipes)
{
    cookRecipes.Recipes.Add(recipe);
}
cookRecipes.SaveChanges();

EF希望您全部进行所需的更改,然后再次调用SaveChanges 。这样,它可以优化数据库通信和sql来执行打开状态和保存状态之间的更改,忽略所有已撤消的更改。 (例如,添加50 000条记录,然后删除其中一半,然后点击SaveChanges只会向数据库添加25 000条记录。永远。)

答案 1 :(得分:2)

也许你可以在添加新对象时禁用Changetracking,这确实会提高性能。

context.Configuration.AutoDetectChangesEnabled = false;

另请参阅更多信息:http://coding.abel.nu/2012/03/ef-code-first-change-tracking/

答案 2 :(得分:1)

EF擅长许多事情,但批量加载不是其中之一。如果您想要高性能批量加载,直接通过数据库服务器执行此操作将比任何 ORM更快。如果您的应用程序唯一的性能限制是批量加载,那么您可能不应该使用EF。

答案 3 :(得分:1)

只是添加其他答案:db4o通常在进程中运行,而EF抽象进程外(SQL)数据库。但是,db4o本质上是单线程的。因此,虽然对于具有一个请求的这个示例来说可能更快,但SQL将比默认的db4o数据库设置更好地处理并发(多个查询,多个用户)。