Bhargav Software Ответов: 1

Проблема с подготовкой запроса .NET LINQ


У нас возникла проблема с запросом linq. В select query несколько таблиц связаны с соединениями. Где фильтры записей были применены к разделу соединения. Этот запрос работал нормально и давал правильный результат в течение последних 8-9 месяцев.
Внезапно потребовалось время около 2 минут, чтобы получить запись с тем же соединением и потребляющим 99% процессора.

Этот запрос используется всегда во время входа пользователя в систему, поэтому он уверен, что он работал нормально в прошлом до момента выпуска.
Может ли кто-нибудь помочь, почему эта проблема возникла внезапно?
var entityList = (from x in db.TableA
                           join y in db.TableB
                           on x.Id equals y.TableC.TableAId into g
                           from d in g.DefaultIfEmpty()
                           where (d.EndDateTime == null && (d == null || d.TableE.PersonID == personId))
                                 && x.EndDateTime == null
                                 && d.TableC.EndDateTime == null
                                 && x.TableE.PersonID == personId
                           select new
                           {
                             Col1 = d != null ? d.TableC.TableD.Id : 0,
                             Col2 = d != null ? d.TableC.Id : 0,
                           }).AsQueryable();


Что я уже пробовал:

Мы проверили индексы таблиц.

Gerry Schmitz

Ты просто гадаешь. Только путем подсчета и синхронизации вы можете указать на определенный раздел кода. Кто-то загрузил вашу базу данных миллионом дубликатов, насколько нам известно.

1 Ответов

Рейтинг:
1

David_Wimbley

Вам нужно посмотреть, что делает базовый SQL, генерируемый entity framework. Затем возьмите тот же sql и запустите его через sql server (предположительно) с включенным анализатором запросов, чтобы увидеть, где находятся горлышки бутылок или отсутствующие индексы (если таковые имеются).

Чтобы зарегистрировать sql, генерируемый entity framework, вам нужно будет сделать что-то вроде этого. Предположим, что вы используете log4net, например.

var log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
db.Database.Log = log.Info;
// or you could do
db.Database.Log = Debug.WriteLine;


Затем сгенерированный sql будет выведен в файл журнала или окно вывода отладки.

Оттуда возьмите этот sql, запустите его в management studio, проанализируйте запрос и настройте свой запрос linq оттуда. Entity framework/linq печально известен тем, что создает какой-то неприятный sql, который не имеет смысла, поэтому у меня есть ощущение, что большая часть вашей нулевой проверки, которую вы делаете в своем запросе, генерирует гигантский sql-оператор, который съедает ваш процессор.


Maciej Los

5ed!