2016-01-01 1 views
1

Я использую Entity Framework 6 для получения объекта, который имеет несколько свойств навигации для глубоко вложенных объектов. Я столкнулся с огромным влиянием производительности, которое было увеличено путем регистрации запросов Entity Framework. У меня есть сто записей в моей самой глубокой сущности (Geocoordinate) и загрузка объекта Session занимает до 8 секунд (я хотел бы менее 1 секунды).Медленная производительность, получающая множество вложенных объектов с использованием Entity Framework

Вот Сущность образец журнала: https://gist.github.com/bbougot/837419c682a75d4741a5

Вот мой код:

 using (var context = new ModelContainer()) 
     { 
      context.Database.Log = msg => Trace.WriteLine(msg); 
      var session= await 
       context.SessionSet.FirstOrDefaultAsync(a => a.Identifier == sessionIdentifier); 
      var result = await Json(session).ExecuteAsync(new CancellationToken()); 
      return ResponseMessage(result); 
     } 

Я извлекая красные сущности моей модели (обратите внимание только один-ко-многим между Маршрут и GeoPosition):

mode

(Ссылка на большой размер изображения: http://i.imgur.com/adRw6br.jpg?1)

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

+0

Вы уверены, что это проблема с EF? Я имею в виду, если вы запускаете аналогичный запрос TSQL, работает ли он быстрее? – Rahul

+0

нет, это примерно то же самое ... Я думаю, что моя модель не оптимизирована. Я упрощу некоторые отношения, тогда производительность должна быть лучше. – Ben

ответ

2

Причина, по которой объект так долго загружается, заключается в том, что вы страдаете от классической проблемы выбора N + 1.

Как вы уже знаете, Entity Framework по умолчанию lazy загружает все свойства навигации, создавая вокруг них динамический прокси-объект. Если он обнаруживает, что прокси-сервер получает доступ (т. Е. Вы следуете за свойством навигации), он выдает запрос в базу данных, чтобы фактически уйти и получить данные. Причина, по которой это влияет на производительность, заключается в том, что каждый запрос к базе данных, который выполняется, имеет определенные служебные данные, связанные с ним (например, задержка на сервере базы данных), поэтому лучшим вариантом является выполнение одного запроса, который возвращает все данные, которые вам нужны за один раз, а не отдельные запросы для каждого отдельного объекта.

Когда речь идет о свойствах коллекции (например, ваше Route -> Geoposition отношения), то все становится еще хуже, потому что Entity Framework будет генерировать отдельный выбор для каждого элемента в коллекции. Вот почему вы видите так много сотен запросов в вашем журнале.

Я попытался отключить отложенную загрузку и использование Включить в нетерпеливую нагрузку моих сущностей, но это еще хуже, я достиг тайм-аут SQL Server.

Использование метода Include - это правильный подход к надежному загрузке свойства навигации как части исходного запроса. Если после Include с соответствующими свойствами навигации вы все еще находите, что ваш запрос занимает слишком много времени, вы должны посмотреть на план выполнения запроса, чтобы увидеть, где находится проблема с производительностью. Отправьте еще один вопрос, если вам нужна помощь в его анализе.

+1

Это решило мою проблему, спасибо! Ключевой была проблема с загрузкой проблематичной сущности. – Ben

 Смежные вопросы

  • Нет связанных вопросов^_^