LINQом из DataTable по индексу?
Я так надеюсь,что все знают что такое индекс на таблице SQL-сервера, для чего нужен и как используется.
Считаем что с сервером все понятно.
Теперь переползаем на клиента - имеем те же данные что на сервере и эти данные достаточно "тяжелые".
Т.е. записи длинные, записей много и записи не сортированы.
Работа с данными (пока) традиционная - через DataTable - загрузили и ищем.
Чтобы не сильно мучатся - ищем LINQом.
Известно, что поиск будет многократный - т.е. любое ускорение - на пользу.
Отсюда два вопроса:
1. Как на DataTable повесить произвольный индекс?
Т.е. есть 150-200 полей и 3 из них мне нужны как индекс.
Про вариант проэмулировать индекс вторичным ключем - слепить вторую таблицу, дистинктнуть в нее эти поля, сделать их первичным ключем и определить реляцию - знаю, но не нравится - хочется именно индекс по таблице без головной боли с поддержанием синхронизации.
2. Как принудить LINQ использовать индекс (пусть и сурогатный) при выполнении поиска?
1. Как на DataTable повесить произвольный индекс?Т.е. есть 150-200 полей и 3 из них мне нужны как индекс.Про вариант проэмулировать индекс вторичным ключем - слепить вторую таблицу, дистинктнуть в нее эти поля, сделать их первичным ключем и определить реляцию - знаю, но не нравится - хочется именно индекс по таблице без головной боли с поддержанием синхронизации.
зачем? новые таблицы вы создавать не желаете, значит остается выбирать записи из ВСЕХ (не пропустить бы чего).
2. Как принудить LINQ использовать индекс (пусть и сурогатный) при выполнении поиска?
элементарно, уоттсон! постройте правильно ваш запрос, и linq его исполнит с высокой точностью.
шукаємо записи, где пропертиз id0: ID0, id1: ID1, id2: ID2
var q = from rec in records where rec.id0 == ID0 &&
rec.id1 == ID1 && rec.id2 == ID2 select rec; (или что вам оттуда нужно выбрать).
или я чего-то недопонл.
нужно, мне кажется, прежде всего между двумя вариантами выбрать: мы согласны что-нибудь заморочить один раз, чтобы потом раз! и достал что надо!
, или не согласны, но тогда мы не можем исключить просмотра при каждом запросе всей таблицы. LINQ'ом, или кем-либо еще. при чем здесь "суррогантый иднеск"?
зачем?
-----
Смотрим чутка выше - в первый пост.
Хочется определять и использовать индекс для ускорения процесса.
остается выбирать записи из ВСЕХ
-----
Когда-то давно удавалось ускорять выполнение с 20-30 минут до десятков секунд просто построив и используя индекс.
Но там он строился по массиву (array) ручками с кучей кода обвязки...
и linq его исполнит с высокой точностью.
-----
Ну а мне помимо точности еще и скорости хочется.
Пусть в твоем records 100K записей.
При этом ID2 принимает 3 значения 1,2,3 при этом 1 - 50К-1, 2 - 50К-1, 3 - две записи.
Сколько надо сканить records чтобы выбрать записи с ID2==3?
при чем здесь "суррогантый иднеск"?
-----
Видимо стоит ознакомится с тем что такое индексы и как они используются.
Здесь можно пошерстить, включая разные ответы и комменты
https://stackoverflow.com/questions/23802401/how-to-get-in...
Но там, как я понял, не строят полноценный индекс, а именно что "эмулируют" его через линк-запрос. Оптимизирует ли при этом сам линк что-то - надо разбираться. Скорее всего нет.
Или там вообще уже готовый индекс в таблице есть, и вопрошающему надо лишь поискать по нему через линк.
"Эмулируют" - в смысле, что пытаются делать запрос с учётом всех столбцов индексса. Но опросить по индексу, как я понимаю, это не сравнить все столбцы. Индекс должен включать в себя какую-то оптимизацию - например, хешнуть все столбцы индекса. Тогда опрос должен идти по этуму жешу (типа как в словаре), а после нахождения строки с нужным хешем нужен подзапрос для вытаскивания конкретных столбцов этой строки.
Впрочем, возможно, что ЛИНК сам распознаёт подобный запрос (со сравнением по куче столбцов) - мол, если это сравнение по столбцам индекса, то он внутри себя переводит этот запрос на поиск по индексу.
Это я всё написал, не очень понимая, что такое индекс и как он работает - так, почитал немного.
А почему вы до сих пор работаете с DataTable и DataSet? Это ж пипец какой-то - по сравнению с EF как в доисторическую эпоху окунулся. Кстати, как раз голостроковые запросы. У меня на древнючем проекте это дерьмо не просто само по себе, а ещё и обёрнутое в самописный фреймворк (с построением запросов вида queryObject.AddWhere(string criteria)... AddOrderBy(string criteria)) и шлифануто сверху корявой первой версией NHibernate. И на EF переходить категорически не хотят.
Как я понял - нормальный индекс не нужен, а нужно работать линком на клиенте так, как будто нормальный индекс есть. Т.е. всё же нахреноверченное на клиенте. Вот я пример показал - "эмулируем" индекс. Но по сути это обычный запрос со сравнением по нескольким полям.
Смотрим чутка выше - в первый пост.Хочется определять и использовать индекс для ускорения процесса.
То есть не просто и рыбку съесть, и далее по присказке?
Тогда что-то такое (например).
хочется еще быстрее: распараллелить по количеству кернов в процессоре.
еще быстрее? использовать python. не знаю, может сишарп тоже может использовать для вычислений gpu?
и далее по присказке?
----
Ну а как иначе?
Существенное из ссылки
Problem:
The DataTable.Select method creates a "System.Data.Select" class instance internally, and this "Select" class creates indexes based on the fields (columns) specified in the query. The Select class makes re-use of the indexes it had created but the DataTable implementation does not re-use the Select class instance hence the indexes are re-created every time DataTable.Select is invoked.
Вот что-то похожее мне и интересно, но в варианте когда индекс создается мною, поддерживается самой таблицей,и ре-юзается.
еще быстрее?
-----
Быстрее бывает разное.
Одно быстрее - число систем в кластере.
Другое быстрее - уменьшение количества операций.
Сейчас меня интересует второе.