Entity Framework - медленный первый запрос

Судя по названию, у меня проблема с первым запросом к базе данных SQL Server с использованием Entity Framework.

У меня есть пытался найти ответ на разных сайтах, но, похоже, на самом деле ни у кого нет решения этой проблемы.

Я загружаю довольно много строк из базы данных, включая две связи 0-многие.

Тесты проводились в Visual Studio 2010 с использованием модели Entity Framework 4.0 и генератора POCO (нет t большая разница во времени между обычными сущностями и объектами POCO). Я также использовал шаблон представлений T4 для предварительной компиляции представлений.

База данных находилась на SQL Server 2008.

Я действительно хотел бы знать, почему первый запрос намного медленнее, чем любые вторичные запросы.

Я также хочу знать, можно ли что-нибудь сделать, чтобы увеличить скорость первого запроса до точки, где она находится в допустимых пределах.

Это большой запрос, и мы можем получить другие запросы, которые еще больше, и это понятно, что они могут быть немного медленными, но 30 секунд - это слишком медленно, чтобы пользователь мог ждать, особенно когда наборы данных могут получить те же данные намного быстрее.

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

Время было следующим:

Приложение для тестирования .NET:

  • Первый запрос: 29,6 секунды
  • Второй запрос: 3,2 секунды

Профилировщик SQL:

  • Первый запрос: 27 секунд
  • Второй запрос: 3,2 секунды

Окно запроса SQL Server

  • Первый запрос: 8 секунд
  • Второй запрос: 4 секунды

Время в приложении измерялось с помощью секундомера класс. Был измерен только запрос, и .ToList () использовался для выполнения запроса.

Тайминги в SQL Server Profiler предназначены для тех же запросов, которые были выполнены в приложении, что показывает, что приложение использует только около 2,6 секунды для заполнения данных объектами.

Последние 27 секунд используются для выполнения запроса на SQL Server.

Глядя на вторичный запрос, время одинаково для приложения и SQL-сервера, но на этот раз выполнение запроса происходит намного быстрее.

Я могу понять, почему приложение не использует время из-за отсутствия новых строк которые нужно преобразовать в объекты, но почему запрос намного быстрее, я ожидал несколько секунд из-за планов выполнения, но не 24 секунды.

Просто для целей тестирования я скопировал SQL, который Entity Framework генерирует и открывает новое окно запроса с отдельным подключением и выполнение запроса в нем.

Как видите, первый запрос занимает 8 секунд, а второй - 4 секунды.

Надеюсь, у кого-то есть предложения.

пс. Прошу прощения за стену текста :)

Редактировать 19-10-2010:
t использовать любое время, потому что нет новых строк, которые нужно преобразовать в объекты, но почему запрос намного быстрее, я ожидал бы несколько секунд из-за планов выполнения, но не 24 секунды.

Просто для целей тестирования я скопировал SQL, который генерирует Entity Framework, открыл новое окно запроса с отдельным подключением и выполнил запрос в нем.

Как вы можете видеть, для первого запроса требуется 8 секунд, а для второго - 4 секунды.

Надеюсь, у кого-то есть предложения.

ps. Прошу прощения за стену текста :)

Редактировать 19-10-2010:
t использовать любое время, потому что нет новых строк, которые нужно преобразовать в объекты, но почему запрос намного быстрее, я ожидал бы несколько секунд из-за планов выполнения, но не 24 секунды.

Просто для целей тестирования я скопировал SQL, который генерирует Entity Framework, открыл новое окно запроса с отдельным подключением и выполнил запрос в нем.

Как вы можете видеть, для первого запроса требуется 8 секунд, а для второго - 4 секунды.

Надеюсь, у кого-то есть предложения.

ps. Прошу прощения за стену текста :)

Редактировать 19-10-2010:

Просто в целях тестирования я скопировал SQL, который генерирует Entity Framework, и открыл новое окно запроса с отдельным подключением и выполнил запрос в нем.

Как вы можете видеть, первый запрос занимает 8 секунд и 4 секунд на секунду.

Надеюсь, у кого-то есть предложения.

ps. Прошу прощения за стену текста :)

Редактировать 19-10-2010:

Просто в целях тестирования я скопировал SQL, который генерирует Entity Framework, и открыл новое окно запроса с отдельным подключением и выполнил запрос в нем.

Как вы можете видеть, первый запрос занимает 8 секунд и 4 секунд на секунду.

Надеюсь, у кого-то есть предложения.

ps. Прошу прощения за стену текста :)

Редактировать 19-10-2010:
Вчера я провел тест, который, кажется, поддерживает то, что строки возвращаются последовательно. Это означает, что когда строка возвращается из базы данных, она немедленно материализуется (если она еще не существует в контексте), затем возвращается следующая строка и т. Д.

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

Я не верю, что это случай чтения SQL Server с жесткого диска. Медленный запрос происходит каждый раз, когда в EF появляется «первый запрос».

пример

  1. Выполнить первый запрос с EF, оператор SQL работает медленнее, чем любой вторичный запрос
  2. Удалить контекст / репозиторий
  3. Создать новый контекст
  4. Выполнить тот же запрос, что и раньше (снова первый запрос медленный, как и оператор SQL)

Это похоже на то, как EF отправляет некоторые параметры вместе с первым запросом, который замедляет работу сервера.

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

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

Я также провел тест, в котором я создал скомпилированный запрос как статический, чтобы он компилировался для всех созданных контекстов.

Затем я создал контекст, выполнила запрос, уничтожила контекст и создала новый, а затем снова выполнила тот же запрос.

Разница была не такой большой, всего несколько секунд, и в самый первый раз, когда я запустил запрос, это все равно заняло столько же времени, сколько и без предварительно скомпилировав его.

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

Действительно ли EF работает только в том случае, если вы ничего не делаете, кроме простейших запросов, которые возвращают только относительно небольшое количество данных?

24
задан marc_s 12 January 2016 в 10:03
поделиться