Есть ли в ADO.Net DataTables индексы? - PullRequest
18 голосов
/ 10 июля 2009

Я использую VSTS 2008 + C # + .Net 3.5 + SQL Server 2008 + ADO.Net. Если я загружаю таблицу из базы данных с помощью DataTable из ADO.Net и в таблице базы данных, я определил пару индексов для таблицы. У меня вопрос: есть ли в ADO.Net DataTable связанный индекс (такой же, как индексы, которые я создал для физической таблицы базы данных), чтобы повысить производительность некоторых операций в DataTable?

спасибо заранее, George

Ответы [ 11 ]

19 голосов
/ 17 декабря 2011

На самом деле вопрос Джорджа не так "плох", как утверждают некоторые. (Я все больше убеждаюсь, что такого понятия, как «плохой вопрос», не существует.)

У меня довольно большая таблица, которую я загружаю в память в объекте DataTable. Много раз делается для строк из этой таблицы, много раз, для различных (и разных) подмножеств, которые я могу легко описать как «ГДЕ ...» предложений SELECT. Теперь с этой DataTable я могу запустить Select () - метод класса DataTable - но он довольно неэффективен.

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

9 голосов
/ 21 ноября 2014

Нет, но, возможно, да.

Вы можете установить свои собственные индексы в DataTable, используя DataView. При изменении таблицы DataView будет перестроен, поэтому индекс всегда должен обновляться.

Я провел несколько стендовых тестов для своего собственного приложения. Я использую DataTable для приближения Boost MultiIndexContainer. Чтобы создать индекс для вызова столбца «Автор», я инициализирую DataTable, а затем DataView ...

_dvChangesByAuthor = 
    new DataView(
        _dtChanges, 
        string.Empty, 
        "Author ASC", 
        DataViewRowState.CurrentRows);

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

            dataRowViews = _dvChangesByAuthor.FindRows(author);
            List<DataRow> returnRows = new List<DataRow>();
            foreach (DataRowView drv in dataRowViews)
            {
                returnRows.Add(drv.Row);
            }

Я создал случайный большой объект DataTable и выполнял запросы с использованием DataTable.Select (), Linq-To-DataSet (с принудительным выполнением путем экспорта в список) и описанным выше методом DataView. Метод DataView победил легко. Linq взял 5000 тиков, Select - более 26000 тиков, DataView - 192 тика ...

LOC=20141121-14:46:32.863,UTC=20141121-14:46:32.863,DELTA=72718,THR=9,DEBUG,LOG=Program,volumeTest() - Running queries for author >TFYN_AUTHOR_047<
LOC=20141121-14:46:32.863,UTC=20141121-14:46:32.863,DELTA=72718,THR=9,DEBUG,LOG=RightsChangeTracker,GetChangesByAuthorUsingLinqToDataset() - Query elapsed time: 2 ms, 4934 ticks; Rows=65 
LOC=20141121-14:46:32.879,UTC=20141121-14:46:32.879,DELTA=72733,THR=9,DEBUG,LOG=RightsChangeTracker,GetChangesByAuthorUsingSelect() - Query elapsed time: 11 ms, 26575 ticks; Rows=65 
LOC=20141121-14:46:32.879,UTC=20141121-14:46:32.879,DELTA=72733,THR=9,DEBUG,LOG=RightsChangeTracker,GetChangesByAuthorUsingDataview() - Query elapsed time: 0 ms, 192 ticks; Rows=65

Итак, если вам нужны индексы для DataTable, я бы предложил DataView, если вы можете справиться с тем фактом, что индекс перестраивается при изменении данных.

7 голосов
/ 29 апреля 2012

Вы можете создать первичный ключ для данных. Операции фильтрации значительно улучшаются, если вы ищете в поле первичного ключа. Проверьте эту ссылку: здесь

4 голосов
/ 07 июля 2012

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

Решение, которое я нашел, состояло в том, чтобы создать DataView для каждого индекса, который я хотел использовать, а затем использовать его методы Find и FindRows для извлечения данных.

DataView создает внутренний индекс для DataTable и фактически для этой цели ведет себя как индекс.

В моем случае мне удалось сократить 10000 запросов с 40 секунд до ОДНОГО !!!

4 голосов
/ 12 июля 2009

Джон выше верен. DataTables отключены в структурах памяти. Они не соответствуют физической реализации базы данных.

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

2 голосов
/ 12 июля 2009

Другие отметили, что DataSet не предназначен для использования в качестве системы базы данных - просто представление данных. Если вы работаете под впечатлением, что DataSet - это база данных, то вы ошибаетесь и, возможно, вам придется пересмотреть вашу реализацию.

Если вам нужна база данных на стороне клиента, рассмотрите возможность использования SQL Compact или SQL Lite, поскольку обе они являются бесплатными распространяемыми системами баз данных, которые можно использовать, не требуя отдельных установок или служб. Если вам нужно что-то более полнофункциональное, SQL Express - следующий шаг.

Чтобы прояснить это, DataSets / Tables используются в разработке .NET для временного хранения данных по мере необходимости. Думайте о них как о результатах запроса SELECT к базе данных; они примерно аналогичны файлам CSV или другим формам табличных данных - вы можете извлекать в них данные из базы данных, работать с данными, а затем передавать изменения обратно в базу данных - но сами по себе они не являются базы данных.

Если у вас есть большая коллекция элементов, которые по той или иной причине вам необходимо хранить в памяти, вы можете подумать о создании облегченного DTO (объект передачи данных, Google it, они очень простые) и загрузки их в Хеш-таблица. HashTables не даст вам никакой формы реляционных данных, но очень эффективен при поиске.

1 голос
/ 01 декабря 2016

Правильный ответ здесь - создать DataView из DataTable, который в соответствии с документом создаст индекс:

DataView создает индекс. Индекс содержит ключи, построенные из одного или нескольких столбцов в таблице или представлении. Эти ключи хранятся в структуре, которая позволяет DataView быстро и эффективно находить строку или строки, связанные со значениями ключа. Операции, использующие индекс, такие как фильтрация и сортировка, видят значительное увеличение производительности. Индекс для DataView создается как при создании DataView, так и при изменении любой информации сортировки или фильтрации. Создание DataView, а затем установка информации сортировки или фильтрации позже приводит к тому, что индекс создается не менее двух раз: один раз при создании DataView и снова при изменении любого из свойств сортировки или фильтра.

1 голос
/ 21 мая 2014

DataTables индексируются, если вы (кодировщик) указываете один или несколько DataColumns в качестве первичного ключа. В целом ADO.NET использует красно-черное дерево для формирования этого индекса, что позволяет осуществлять поиск во время журнала. Этот первичный ключ не устанавливается автоматически на основе какого-либо основного ключа от поставщика данных.

1 голос
/ 13 января 2010

DataTables имеют поле PrimaryKey, которое может служить индексом (они все равно уже быстрые). Это поле не копируется из первичных ключей базы данных (хотя это может быть неплохо).

0 голосов
/ 06 февраля 2013

Мое чтение документов состоит в том, что правильный способ достижения этого (при необходимости) заключается в использовании AsDataView для получения DataView (или LinqDataView), привязанного к базовой таблице. Если ваш DataTable инвариантен, тогда DataView может быть статическим, чтобы избежать избыточной переиндексации.

Я сейчас расследую Linq to DataSet, и этот вопрос был мне полезен, так что спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...