#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 дней, но была информация, которая не отображалась, в которой нуждались наши пользователи, поэтому мы предоставили им эту опцию. Я реализовал другое предложение, и оно значительно улучшило производительность. Спасибо за предложение.