Проблема с Perf Linq2Sql - PullRequest
       13

Проблема с Perf Linq2Sql

3 голосов
/ 09 августа 2011

Я пытаюсь улучшить производительность в приложении, которое интенсивно использует Linq2Sql.Я нашел конкретный метод, который действительно медленный.Это противное, вложенное, .Sum() утверждение.При выполнении для возврата данных требуется чуть более 30 секунд.Всего строк данных может быть 3000. Если я возьму sql, сгенерированный LinqPad, и запустю его, я верну данные менее чем за секунду.

Я в недоумении относительно того, что вернется сюда.Это должно быть отфильтровано предложением where, верно?Я также представляю, что это будет работать изнутри.начиная с где, затем суммируйте все результаты, затем суммируйте каждый в T2, затем суммируйте каждый в T1.

ParentTable.Table1.Sum
(
 t1=>
  t1.Table2.Sum
  (
   t2=>
     t2.Table3.Where(t3=>t3.Table4.Id==275).Sum(t3=>t3.Score)
  )
)

Чтобы усложнить ситуацию, LinqPad может выполнить тот же оператор менее чем за полсекунды.

Наверное, мой вопрос: почему такая разница в скоростях Linq2Sql и TSql?Linq возвращает все строки и фильтрует их в окне приложения?

Теперь веб-приложение повторно использует один и тот же DataContext в течение всего времени сеанса пользователей.У меня всегда было впечатление, что вы должны избавляться от него после каждой операции.Может ли это быть проблемой?

Позвольте мне добавить, что при профилировании SQL (при запуске из приложения) мне не о чем беспокоиться.Чтения <15, загрузка ЦП <5, запись - ничто, длительность - не более 20. Поэтому я уверен, что это не выполнение операторов, а некоторая обработка, выполняемая LINQ2Sql. </p>

1 Ответ

0 голосов
/ 09 августа 2011

Мне кажется, я понял, что происходит.

Отношения данных не так просты, как это делает LINQ.Таблица1 имеет ссылку на Таблицу2. Таблица2 ссылается на Таблицу3 Однако Таблица4 не связана напрямую с T3, есть еще 2 пути.

Это не должно влиять на что-либо, но затененочастичный класс объекта Table1 - это пользовательский глобальный словарь "кэширования".Каждый раз, когда вы запрашиваете НИЧЕГО из Таблицы 1, он удостоверяется, что каждая запись из этой таблицы загружена в память.Один и тот же шаблон существует для всех объектов.

Таким образом, по сути, делая эту быструю и простую сумму, она загружает КАЖДУЮ запись из всех 6 таблиц (t1, t2, t3, t3b, t3c, t4) в памятьи ТО делает сумму.

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

Вау ... просто вау!

...