Entity Framework зависает после завершения запроса до закрытия соединения - PullRequest
0 голосов
/ 08 сентября 2018

Я пытаюсь улучшить производительность относительно сложного запроса структуры объекта. Используя действие DbContext.Database.Log, я проверил вывод при выполнении основного интересующего запроса и заметил кое-что странное. Согласно журналу, сам запрос занимает всего ~ 10000 мс, однако между завершением запроса и закрытием соединения проходит более минуты. Я понятия не имею, что происходит в это время, поскольку журнал показывает пустую строку. Вот вывод:

2018-09-07 14: 10: 34,641 [1] INFO EntityDataRepository [jobInstanceID: 0] - - Выполнение в 9/7/2018 14:10:34 -07: 00

2018-09-07 14: 10: 46,421 [1] INFO EntityDataRepository [jobInstanceID: 0] - - Завершено за 11776 мс с результатом: SqlDataReader

2018-09-07 14: 10: 46,458 [1] ИНФО EntityDataRepository [jobInstanceID: 0] -

2018-09-07 14: 11: 48,667 [1] INFO EntityDataRepository [jobInstanceID: 0] - Закрытое соединение в 09.07.2017 14:11:48 -07: 00

Может ли кто-нибудь объяснить мне, что здесь происходит? Ниже приведена упрощенная / общая версия кода:

(from child in entities.SelectMany(e => e.children.Where(childFilter))
join read in childReads on child.ID equals read.childID
join readType in readTypes on read.readTypeID equals readType.ID
where readFilter
select new {child, read, readType}).ToList()

1 Ответ

0 голосов
/ 08 сентября 2018

2018-09-07 14: 10: 46,421 1 INFO EntityDataRepository [jobInstanceID: 0] - - Завершено за 11776 мс с результатом: SqlDataReader

Это означает, что SqlCommand.ExecuteReader() завершено, и сервер начинает возвращать строки клиенту. Запрос в SQL Server все еще выполняет на данный момент. Возможно, он помещал в буфер все результаты запроса или, возможно, только что нашел и возвратил первые несколько совпадающих строк, используя план потокового запроса. Таким образом, для выполнения IQueryable<T>.ToList() запрос должен быть завершен на сервере, строки результата должны быть переданы клиенту, а EF должен прочитать строки и материализовать их в экземпляры класса типа T.

Работу на стороне клиента можно проанализировать с помощью Visual Studio Profiler , счетчиков производительности или System.Diagnostics.Process .

SQL Server отслеживает статистику выполнения запросов для запросов в кэше плана и для всех запросов, если используется Query Store в SQL 2016+. Статистика покажет вам истекшее время запроса, которое включает в себя время ожидания клиентом для чтения (и обработки) строк и всех других ожиданий, а также «рабочее время», которое представляет собой процессорное время, используемое запросом. Хранилище запросов в SQL 2017 и базе данных SQL Azure также отслеживает статистику ожидания для каждого запроса, поэтому вы можете различать ожидания на клиенте (ASYNC_NETWORK_IO) и другие ожидания, такие как чтение файла данных (PAGEIOLATCH), ожидания блокировки (LCK_*_*) ) и т. д.

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