Почему EF4 Code First такой медленный при хранении объектов? - PullRequest
12 голосов
/ 27 июля 2010

В настоящее время я изучаю использование db4o хранилища для моего веб-приложения.Я очень рад, как легко работает db4o.Поэтому, когда я читаю о подходе Code First, который мне нравится, мне нравится то, что способ работы с EF4 Code First очень похож на работу с db4o: создайте свои доменные объекты (POCO), бросьте их в db4o и никогда не оглядывайтесь назад.

Но когда я сравнивал производительность, EF 4 работал ужасно медленно.И я не мог понять, почему.

Я использую следующие объекты:

</p>

<p>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(); } }</p>

<pre><code>    public void AddPreparation(RecipePreparation preparation) 
    {
        this._RecipePreparations.Add(preparation);
    }
}

открытый класс RecipePreperation {public String Name {get;задавать;} public String Описание {get;задавать;} public int Rating {get;задавать;} public List Steps {get;задавать;} общедоступные теги списка {get;задавать;} public int ID {get;задавать;}}

Чтобы проверить производительность, я создаю новый рецепт и добавляю 50.000 RecipePrepations.Затем я сохранил объект в db4o следующим образом:

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

Это занимает около 13 000 (мс)

Я храню вещи с EF4 в SQL Server 2008 (Express, локально) следующим образом:

cookRecipes.Recipes.Add(recipe1);
cookRecipes.SaveChanges();

И это занимает 200.000 (мс)

Как же db4o в 15 (!!!) раз быстрее, чем EF4 / SQL?Я скучаю по секретной кнопке турбо для EF4?Я даже думаю, что db4o можно было сделать быстрее?Поскольку я не инициализирую файл базы данных, я просто позволю ему динамически расти.

Ответы [ 4 ]

3 голосов
/ 27 июля 2010

Вы называли SaveChanges() внутри петлей?Не удивительно, что это медленно!Попробуйте сделать следующее:

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

EF ожидает от вас всех изменений, которые вы хотите, а затем вызовите SaveChanges один раз .Таким образом, он может оптимизировать взаимодействие с базой данных и sql для выполнения изменений между состоянием открытия и сохранением состояния, игнорируя все изменения, которые вы отменили.(Например, добавление 50 000 записей, затем удаление половины из них, а затем нажатие SaveChanges добавит только 25 000 записей в базу данных. Всегда.)

2 голосов
/ 12 февраля 2013

Возможно, вы можете отключить отслеживание изменений при добавлении новых объектов, это действительно повысит производительность.

context.Configuration.AutoDetectChangesEnabled = false;

см. Также для получения дополнительной информации: http://coding.abel.nu/2012/03/ef-code-first-change-tracking/

1 голос
/ 24 августа 2010

Просто добавим к другим ответам: db4o обычно выполняется в процессе, в то время как EF абстрагирует базу данных вне процесса (SQL). Однако db4o по сути однопоточный. Таким образом, хотя это может быть быстрее для этого одного примера с одним запросом, SQL будет обрабатывать параллелизм (несколько запросов, несколько пользователей) намного лучше, чем настройка базы данных db4o по умолчанию.

1 голос
/ 27 июля 2010

EF превосходит во многих отношениях, но массовая загрузка не является одним из них.Если вам нужна высокопроизводительная массовая загрузка, выполнение ее непосредственно через сервер БД будет быстрее, чем любая ORM.Если единственным ограничением производительности вашего приложения является массовая загрузка, то вам, вероятно, не следует использовать EF.

...