Подтвердить что ты не робот

Почему EF4 Code First так медленно при хранении объектов?

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

Но когда я сравнивал производительность, 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);
    }
}

Открытый класс RecipePreparation   {       public String Name {get; задавать; }       public String Описание {get; задавать; }       public int Рейтинг {get; задавать; }       открытые этапы списка {get; задавать; }       public List Tags {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? Я пропустил секретную кнопку turbo для EF4? Я даже думаю, что db4o можно сделать быстрее? Поскольку я не инициализирую файл базы данных, я просто позволяю ему динамически расти.

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

context.Configuration.AutoDetectChangesEnabled = false;

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

Ответ 3

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

Ответ 4

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