Могу ли я повысить производительность этого запроса linq?

#vb.net #linq

#vb.net #linq

Вопрос:

У меня есть форма, которую при загрузке я заполняю открытыми счетами (более 85 000 записей). Пользователь имеет возможность выбирать «закрытые» счета-фактуры, которые я по умолчанию использую в выпадающем списке daysOld с 60. (Это позволяет мне выполнять фоновую задачу, которая извлекает все закрытые счета-фактуры за последние 60 дней (более 100 000 записей).). Затем пользователь может выбрать 60, 120, 360, 540, 720 из выпадающего списка. Если пользователь выберет 720 , я повторно запущу запрос и верну все закрытые счета за последние 720 дней (3,2 миллиона записей). Однако, если пользователь выбирает один из этих дней с большим количеством дней, а затем повторно выбирает меньший день (например, 60) Я не хочу повторно запускать запрос, я хочу извлечь нужные мне данные из набора записей, который у меня уже есть.

_taClosed это список (объектов), который я возвращаю на основе количества выбранных дней.

 Dim tot = (From tak In _taClosed
          Where tak.DateOfInvoice > DateTime.Now.AddDays(-1 * cmbDaysOld.SelectedItem)).CopyToDataTable()
  

Пожалуйста, обратите внимание, что для выполнения запроса linq требуется 5 секунд, что кажется долгим временем. Любые предложения по увеличению производительности приветствуются.

Комментарии:

1. время, которое требуется, меньше связано с LINQ и с объемом данных.

2. Сам запрос занимает 5 секунд или он включает в себя другую операцию (например, copytodatable)? Каково состояние вашего индекса?

3. @TMcKeown Я подумал, что это может быть из-за объема данных, которые я просматривал, но я не был уверен, что linq был настроен правильно, наиболее эффективным способом.

4. @SimonBelanger для выполнения copytodatable требуется 5 секунд.

5. Запрос не выполняет ничего, кроме сравнения одной даты, это объем данных.

Ответ №1:

Единственное, что я вижу, это DateTime.Now.AddDays() вызов внутри лямбда-выражения. Вы должны вычислить его только один раз, перед вводом запроса:

 Dim dateFrom = DateTime.Now.AddDays(-1 * cmbDaysOld.SelectedItem)
Dim tot = (From tak In _taClosed
          Where tak.DateOfInvoice > dateFrom).CopyToDataTable()
  

Но я не думаю, что это будет иметь большое значение.

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

Кроме того, вы показываете все элементы сразу? Нет смысла извлекать все записи, когда вы показываете только несколько (из-за разбивки на страницы).

Комментарии:

1. Я действительно видел, что такого рода модификации имеют большое значение в запросе linq (перенос работы из лямбда-выражения, если это можно сделать заранее). Тем не менее, работа, которую я выполнял в lambda, заключалась в обработке строк, которая, вероятно, более интенсивна, чем изменение вашего DateTime.

2. Это будет иметь значение, но я не уверен, насколько оно будет большим.

3. Это действительно имело огромное значение, вместо того, чтобы linq занимал 5 секунд, требуется 1 секунда. Спасибо.

Ответ №2:

С 3,2 миллионами записей я подозреваю, что исходное хранилище данных будет быстрее выполнять поиск по запросу linq в памяти.

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

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

Комментарии:

1. У меня есть строка фильтра в моем ultrawingrid, в которой я разрешаю пользователю фильтровать данные. Я сам и мой менеджер считаем, что мы возвращаем слишком много данных, но наши пользователи настаивают на том, что они им нужны. Изначально у нас были данные за 60 дней, но была информация, которая не отображалась, в которой нуждались наши пользователи, поэтому мы предоставили им эту опцию. Я реализовал другое предложение, и оно значительно улучшило производительность. Спасибо за предложение.