Ваш сценарий "первого запуска", как правило, представляет собой одноразовую статическую инициализацию DbContext. Именно здесь DbContext впервые выполняет свои сопоставления и будет выполняться при выполнении первого запроса. Типичный подход, позволяющий избежать этого для пользователя, заключается в простом запросе "прогрева", который выполняется при запуске службы.. Например, после инициализации вашей службы, просто введите что-то вроде следующего:
// Warm up the DbContext
using (var context = new AppDbContext())
{
var hasUser = context.Users.Any();
}
Это также служит для быстрой проверки при запуске, что база данных доступна и отвечает. Сам запрос выполнит очень быструю операцию, но в это время DbContext разрешит свои сопоставления, поэтому любые вновь созданные экземпляры DbContext будут отвечать без каких-либо затрат во время запроса.
Что касается необработанной производительности, если ожидается, что это не запрос, который займет некоторое время и свяжет запрос, не делайте этого async
. Асинхронные запросы не быстрее, на самом деле они немного медленнее. С помощью async
запросы к DbContext направлены на обеспечение того, чтобы ваш поток веб-сервера / приложения реагировал во время обработки потенциально дорогостоящих операций с базой данных. Если вы хотите получить ответ как можно быстрее, используйте синхронный вызов.
Затем убедитесь, что все поля, по которым вы проводите фильтрацию, в данном случае Валюта, проиндексированы. Наличие поля с именем Валюта в вашей сущности в виде строки, а не идентификатора валюты FK (int
) указание на запись валюты уже является дополнительным расходом на индексацию, поскольку индексы целых чисел меньше/быстрее, чем индексы строк.
Вам также не нужно беспокоиться о AsNoTracking
при использовании Count
запрос. AsNoTracking
применяется исключительно в тех случаях, когда вы возвращаете объекты (ToList
/ToArray
/Single
/First
и т.д.) , Чтобы избежать того, чтобы DbContext удерживал ссылку на возвращаемую сущность. Когда вы используете Count
/Any
или проекция для возврата свойств из сущностей с использованием Select
объект, возвращенный для отслеживания, отсутствует.
Также учитывайте задержку в сети между местом, где выполняется код вашего приложения, и сервером базы данных. Это одна и та же машина или в игре есть сетевое подключение? Как это соотносится при выполнении запроса SSMS? С помощью профилировщика вы можете увидеть, что SQL EF на самом деле отправляет в базу данных. Все остальное с точки зрения времени-это затраты: передача запроса в базу данных, Возврат полученных данных запрашивающему, анализ этого ответа. (Если в случае, когда вы возвращаете сущности, выделяете, заполняете, сверяете с существующими ссылками и т. Д... В случае подсчетов и т. Д. проверка существующих ссылок)
Наконец, чтобы обеспечить максимальную производительность, убедитесь, что время жизни ваших DbContexts сокращено. Если DbContext остается открытым и к нему было выполнено несколько запросов отслеживания (выбор сущностей без AsNoTracking
) эти отслеживаемые ссылки на объекты накапливаются и могут негативно повлиять на производительность будущих запросов, даже если вы используете AsNoTracking
по мере того как EF проверяет, отслеживаются ли ссылки на объекты, которые могут быть применимы/связаны с вашими новыми запросами. Много раз я видел, как разработчики предполагают, что DbContexts "дороги", поэтому они предпочитают создавать их как можно меньше, чтобы избежать этих затрат, только чтобы со временем сделать операции более дорогими.
Учитывая все это, EF никогда не будет таким быстрым, как необработанный SQL. Это ORM, предназначенный для обеспечения удобства .Сетевые приложения, когда дело доходит до работы с данными. Это удобство в работе с классами сущностей вместо того, чтобы каждый раз очищать и писать свой собственный необработанный SQL, сопряжено с определенными затратами.