2015-05-05 4 views
2

Я пытаюсь улучшить производительность, используя DataTable.Select, добавив первичный ключ в таблицу, но все еще занимает слишком много времени, всего за 1200 строк. С и без Первичного ключа разница во времени составляет всего 3-4 секунды (для DataTable.Select).Добавление первичного ключа в datatable

Теперь, насколько я знаю, производительность Linq не зависит от добавления первичного ключа. Производительность для меня бесполезна из-за создания массива коллекции Datarow, который, как я думаю, является узким местом.

Тогда в чем заключается использование первичного ключа здесь?

+1

Его более или менее вещь, используемая в связи с Бэкэнд-БД за DataTable. Для чистых локальных данных pk будет полезен только для некоторых вещей, таких как слияние. В чем причина такого сравнения? Использование DataTable без бэкэда выглядит плохой выбор, если вы не знаете больше деталей. – Ralf

+0

@ Ralf - 'pk будет полезен только с определенными вещами, как слияние' Слияние чего? Вы можете объяснить. Моя цель - выбор для 200-300 строк в цикле. Поэтому я хочу, чтобы выбор был быстрым. –

+1

Я не уверен, но я думаю, что ПК является ограничением и не создает индекс. –

ответ

1

Первичный ключ A DataTable внутренне поддерживает индекс отдельно от порядка строк, и вы правы, что Select может быть оптимизирован для обработки фильтра на первичном ключе в качестве специального случая. К сожалению, это не было сделано, и Select просто просматривает все записи один за другим и оценивает фильтр.

Причина этого еще медленнее, чем ваша версия LINQ, поскольку фильтр, который вы передаете в виде строки, сначала должен быть проанализирован, тогда он преобразуется в дерево выражений (не LINQ-версия деревьев выражений) и оценщик выражения затем действует как интерпретатор. Ваша версия LINQ генерирует код CIL, который выполняет фильтрацию, которая будет преобразована в собственный код во время выполнения. Не требуется переводчик.

Вы можете получить выгоды от первичного ключа с помощью DataRowCollection.Find:

var rows = lst.Select(key => dtsrc.Rows.Find(key)).Where(row => row != null).ToList(); 

Если lst может содержать дубликаты ключей, вам нужно удалить их первыми. Вы можете использовать метод Enumerable.Distinct(), или вы можете использовать HashSet<int> с самого начала (если вас не волнует порядок ваших строк).

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