DataView.RowFilter Vs DataTable.Select() vs DataTable.Rows.Find()
Учитывая следующий код:
Dataview someView = new DataView(sometable)
someView.RowFilter = someFilter;
if(someView.count > 0) { …. }
Довольно много статей, которые говорят, что Datatable.Select() лучше, чем использование DataViews, но это до VS2008.
Решено: Тайна DataView плохой производительности с большими наборами записей
Массив DataRecord и DataView: драматическая разница в производительности
Googling по этой теме Я нашел несколько статей/форумов, в которых упоминается Datatable.Select() сам по себе довольно глючит (не уверен в этом) и неэффективен в различных сценариях.
На этом (Best Practices ADO.NET) тема на msdn предлагается, что если есть первичный ключ, определенный на datatable, ) или find() следует использовать insted of Datatable.Select().
В этой статье здесь (.NET 1.1) сравниваются все три подхода плюс еще пара. Но это для версии 1.1, поэтому не уверен, что они действительны еще сейчас. Accroding к этому DataRowCollection.Find() превосходит все подходы и Datatable.Select() превосходит DataView.RowFilter.
Итак, я очень смущен тем, что может быть лучшим подходом к поиску строк в datatable. Или нет единого хорошего способа сделать это, в зависимости от сценария существует несколько решений?
Ответы
Ответ 1
Вы ищете "лучший подход к поиску строк в datatable", поэтому я сначала должен спросить: "лучше" для чего? Я думаю, что любая техника имеет сценарии, где она может быть лучше других.
Сначала рассмотрим DataView.RowFilter
: DataView имеет некоторые преимущества в привязке данных. Его очень ориентированный взгляд, поэтому он обладает мощными функциями сортировки, фильтрации или поиска, но создает некоторые накладные расходы и не оптимизирован для производительности. Я бы выбрал DataView.RowFilter
для небольших наборов записей и/или где вы воспользуетесь другими функциями (например, прямой привязкой данных к представлению).
Все данные о DataView, которые вы можете прочитать в старых сообщениях, по-прежнему применяются.
Во-вторых, вы должны предпочесть DataTable.Rows.Find
над DataTable.Select
, если вам нужен только один клик. Зачем? DataTable.Rows.Find возвращает только одну строку. По сути, когда вы указываете первичный ключ, создается двоичное дерево. У этого есть некоторые накладные расходы, связанные с этим, но значительно ускоряет извлечение.
DataTable.Select
работает медленнее, но может пригодиться, если у вас есть несколько критериев и не заботятся об индексированных или неиндексированных строках: он может найти в основном все, но не оптимизирован для производительности. По существу, DataTable.Select должен пройти всю таблицу и сравнить каждую запись с критериями, которые вы прошли.
Надеюсь, вы найдете этот небольшой обзор полезным.
Я бы предложил взглянуть на в этой статье, это было полезно для меня в вопросах производительности, Этот пост содержит некоторые цитаты из него.
Немного ОБНОВЛЕНИЕ:
Кстати, это может показаться немного не относящимся к сфере вашего вопроса, но это почти всегда самое быстрое решение для фильтрации и поиска на бэкэнде. Если вы хотите простоту и иметь SQL Server в качестве backend и .NET3 + на клиенте, перейдите на LINQ-to-SQL. Поиск объектов Linq очень удобен и создает запросы, которые выполняются на стороне сервера. Хотя LINQ-to-Objects также очень удобная, но и более медленная. Если вы уже не знали...
Ответ 2
Сообщение Thomashaid прекрасно подводит итог:
-
DataView.RowFilter
предназначен для привязки.
-
DataTable.Rows.Find
предназначен для поиска только с помощью первичного ключа.
-
DataTable.Select
предназначен для поиска по нескольким столбцам, а также для указания порядка.
Избегайте создания многих элементов DataView в цикле и использования их RowFilters для поиска записей. Это значительно снизит производительность.
Я хотел добавить, что DataTable.Select
может использовать индексы. Вы можете создать индекс в DataTable, создав DataView и указав порядок сортировки:
DataView dv = new DataView(dt);
dv.Sort = "Col1, Col2";
Затем, когда вы вызываете DataTable.Select()
, он может использовать этот индекс при запуске запроса. Мы использовали этот метод для серьезного повышения производительности в тех местах, где мы используем один и тот же запрос много раз. (Обратите внимание, что это было до того, как Linq существовал.)
Трюк заключается в правильном определении порядка сортировки для оператора Select
. Поэтому, если ваш запрос "Col1 = 1 и Col2 = 4", тогда вам понадобится "Col1, Col2", как в приведенном выше примере.
Обратите внимание, что создание индекса может зависеть от фактических вызовов для создания DataView. Нам пришлось использовать конструктор new DataView(DataTable dt)
, а затем указать свойство Sort на отдельном шаге. Поведение может немного измениться в разных версиях .NET.