База данных Entity Framework 6.2 сначала прогревается
У меня есть проект EF 6.2 в моем решении MVC.
Он использует базу данных SQL-сервера и имеет около 40 таблиц со многими внешними ключами.
Первый запрос очень медленный, 20 секунд.
Я сразу же снова захожу на ту же страницу, меняя пользовательский параметр, и запрос занимает менее 1 секунды.
Так что это похоже на проблему разогрева в EF6. Это нормально, и есть множество вещей, которые я могу сделать, чтобы разобраться.
- Кеш модели (часть EF6.2) выглядит полезным, но везде, где я читал об этом, сначала указывается модель. Сначала ничего о БД. Будет ли это все еще работать с БД в первую очередь?
- Также есть мощные инструменты Entity Framework 6, которые позволяют мне создавать представления. Пробовал это, и это, кажется, не имеет никакого значения. Это все еще действительный маршрут?
- Есть еще идеи?
2 ответа
Итак, ответом было обновить EF до 6.2, а затем использовать новейшую функцию:
public class MyDbConfiguration : DbConfiguration
{
public MyDbConfiguration() : base()
{
var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
SetModelStore(new DefaultDbModelStore(path));
}
}
для полной истории проверьте эту ссылку: https://entityframework.net/why-first-query-slow
Вы получите небольшой прирост производительности при запуске, но тогда все будет двигаться намного быстрее.
Для любого, кто использует веб-приложение Azure, вы можете использовать слот для развертывания ( https://stackify.com/azure-deployment-slots/), это позволит вам опубликовать в непроизводственный слот, а затем прогреть его перед заменой в слот производства.
EF DbContexts несут разовые затраты на разрешение сопоставлений их сущностей. Для веб-приложений вы можете уменьшить это, запустив ваше приложение, запустив простой запрос к DbContext, который "запускает" эту разминку, а не во время вашего первого запроса, инициируемого пользователем. Простое обновление контекста не запускает инициализацию, а выполнение запроса. Так что для ASP.Net MVC на Application_Start
после инициализации всего:
using (var context = new MyContext())
{
var warmup = context.MyTable.Count(); // against a small table.
}
Вы можете проверить это поведение с помощью модульных тестов, имея набор временных тестов, которые читают данные из DbContext, и устанавливая точку останова в DbContext. OnModelCreating
событие. Он будет выполнен только один раз из первого теста с первым запросом. Вы можете добавить OneTimeSetUp
в настройке тестового оборудования для запуска перед тестами с приведенным выше примером быстрого подсчета, чтобы понести эти расходы до измерения производительности тестовых прогонов.