Как видно из названия, у меня возникла проблема с первым запросом к базе данных SQL Server с использованием Entity Framework.
Я пытался найти ответ на разных сайтах, но, похоже, на самом деле ни у кого нетРешение этой проблемы.
Я загружаю довольно много строк из базы данных, включая два отношения 0-много.
Тесты проводились в Visual Studio 2010 с использованием модели Entity Framework 4.0 игенератор POCO (нет большой разницы во времени между обычными объектами и объектами POCO).Я также использовал шаблон представлений T4 для предварительной компиляции представлений.
База данных была на SQL Server 2008.
Что я действительно хотел бы знать, так это то, почему первый запрос намного медленнее.чем любые вторичные запросы.
Я также хочу знать, можно ли что-то сделать, чтобы увеличить скорость первого запроса до точки, где он находится в допустимых пределах.
Это большой запроси мы можем получить другие запросы, которые даже больше, и понятно, что они могут быть немного медленными, но 30 секунд слишком медленные для пользователя, чтобы ждать, особенно когда наборы данных могут получить те же данные намного быстрее.
Я провел несколько временных тестов, чтобы попытаться выяснить, в чем заключается проблема, и я был немного удивлен, увидев, что это выглядит так, как будто SQL Server работает медленно в первом запросе.
Время былоследующее:
.NET-приложение для тестирования:
- Первый запрос: 29,6 секунд
- Второй запрос: 3,2 секунды
SQL Profiler:
- Первый запрос: 27 секунд
- Второй запрос: 3,2 секунды
Окно SQL Server Query
- Первый запрос: 8 секунд
- Второй запрос: 4 секунды
Время в приложении измерялось с классом Stopwatch
.Был измерен только запрос, и для его выполнения использовалось .ToList()
.
Синхронизация в SQL Server Profiler относится к тем же запросам, которые были выполнены в приложении, что показывает, что приложение использует только 2,6 секунды.для заполнения данных в объектах.
Последние 27 секунд используются для выполнения запроса на SQL Server.
Глядя на дополнительный запрос, сроки одинаковы как для приложения, так и для сервера SQL, нов этот раз выполнение запроса выполняется намного быстрее.
Я могу понять, почему приложение не использует время, потому что нет новых строк, которые необходимо преобразовать в объекты, но почему запрос намного быстрее, яожидал бы нескольких секунд из-за планов выполнения, но не 24 секунд.
Просто для целей тестирования я скопировал SQL, который генерирует Entity Framework, и открыл новое окно запроса с отдельным соединением и выполнил запрос в нем..
Как видите, на первый запрос уходит 8 секунд.4 секунды за секунду.
Надеюсь, у кого-то есть предложения.
пс.Я извиняюсь за стену текста:)
Edit 19-10-2010:
Вчера я провел тест, который, кажется, подтверждает, что строки возвращаются последовательно.Это означает, что когда строка возвращается из базы данных, она сразу материализуется (если она еще не существует в контексте), тогда возвращается следующая строка и т. Д.
Вот почему кажется, что запросзанимают много времени на сервере базы данных, потому что время материализации включено в тайминги профилировщика SQL Server.
Я не верю, что это случай чтения SQL Server с жесткого диска.Медленный запрос происходит каждый раз, когда в EF появляется «первый запрос».
ex.
- Запустите первый запрос с EF, оператор SQL будет медленнее, чем любой вторичный запрос
- Удалите контекст / хранилище
- Создайте новый контекст
- Запустите тот же запрос, что и раньше (опять первый запрос медленный и оператор SQL)
Это похоже на то, что EF отправляет некоторые параметры вместе с первым запросом, который замедляет работу сервера.
Что касается компиляции запроса, насколько я помню, запрос компилируется при первом использовании, а это означает, чтовыполнение первого запроса займет еще больше времени.
Вторичные запросы будут быстрее, но скорость вторичных запросов не является проблемой.
Я также провел тест, в котором я создал скомпилированный запрос какстатический, чтобы он был скомпилирован для всех созданных контекстов.
Затем я создал контекст, выполнил запрос, уничтожил контекст и создал новый, и снова выполнил тот же запрос.
Разница не была такой большой, всего несколько секунд, и в первый раз, когда я запускал запрос, он по-прежнему длился столько же, сколько и без предварительной компиляции.
Что касается генерации представления, мы уже реализовали этоиспользование шаблонов T4.
Действительно ли ответ заключается в том, что EF работает, только если вы ничего не делаете, кроме самых простых запросов, которые возвращают толькосравнительно небольшой объем данных?