Как максимизировать производительность? - PullRequest
2 голосов
/ 06 февраля 2012

У меня есть проблема, которую я не могу обойти, как бы я ни старался.

Эта компания работает в области анализа рынка и имеет довольно большие таблицы (строки 300K - 1M) и МНОГО столбцов (подумайте250-300), по которым мы делаем некоторые расчеты.

Я попытаюсь прямо перейти к проблеме:

Проблема заключается в фильтрации данных.Все базы данных, которые я пробовал до сих пор, слишком медленны, чтобы выбирать данные и возвращать их.

В настоящий момент я сохраняю всю таблицу в памяти и выполняю фильтрацию с использованием динамического LINQ.

Однако,хотя это довольно быстро (около 100 мс для фильтрации 250 000 строк), мне нужны лучшие результаты, чем эта ...

Есть ли способ изменить что-то в моем коде (не модель данных), что может ускоритьфильтрация вверх?

Я пытался использовать:

DataTable. Выберите, что медленно.Динамический LINQ, который лучше, но все еще слишком медленный.Обычный LINQ (только для целей тестирования), который почти достаточно хорош.Извлечение из MySQL и последующая обработка - медленная.

В начале этого проекта мы думали, что какая-то высокопроизводительная база данных сможет справиться с этим, но я попытался:

H2 (IKVM) HSQLDB (скомпилированный ODBC-драйвер) CubeSQL MySQL SQL SQLite ...

И все они очень медленно взаимодействуют с .NET и получают результаты.

Iтакже пытался разбить данные на куски и объединить их позже во время выполнения, чтобы уменьшить общий объем данных, которые необходимо отфильтровать.

Есть ли какой-нибудь способ в этой вселенной, который я могу сделать так быстрее?

Заранее спасибо!

ОБНОВЛЕНИЕ

Я просто хочу добавить, что я не создал эту базу данных.

Чтобы добавить некоторые цифры,если я сделаю простой выбор из 2 полей в окне запроса к базе данных (SQLyog), например, так: (имя_символа проиндексировано):

SELECT key1, key2 FROM table1 WHERE filter1 = filterValue1

Это займет 125 миллисекунд на 225639 строках.

Почему это так медленно?Я проверил 2 разные коробки.

Конечно, они должны изменить что-то, очевидно?

1 Ответ

5 голосов
/ 06 февраля 2012

Вы не объясняете, что именно вы хотите сделать, или почему важна фильтрация большого количества строк. Почему должно иметь значение, как быстро вы можете фильтровать 1М строк, чтобы получить агрегат, если ваша база данных может предварительно рассчитать этот агрегат для вас? В любом случае кажется, что вы используете неправильные инструменты для работы.

С одной стороны , 1M строк - это небольшое количество строк для большинства баз данных. Пока у вас есть правильные индексы, запросы не должны быть большой проблемой. Я подозреваю, что либо у вас нет индексов в столбцах запросов, либо вы хотите выполнять специальные запросы для неиндексированных столбцов.

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

Все базы данных, используемые для целей анализа, используют специальные структуры данных, которые требуют преобразования ваших данных в форму, которая им нравится. Для типичных реляционных баз данных вы должны создать схемы типа «звезда», которые объединяются с кубами для предварительного расчета агрегатов. Базы данных столбцов хранят данные в столбчатом формате, обычно в сочетании со сжатием для достижения быстрых аналитических запросов, но они требуют, чтобы вы учились запрашивать их на их собственном языке, который может сильно отличаться от языка SQL, к которому привыкли большинство людей.

С другой стороны, способ запроса (LINQ или DataTable.Select или любой другой) оказывает минимальное влияние на производительность. Выбор правильной структуры данных гораздо важнее.

Например, использование словаря <> намного быстрее, чем использование любого из методов, которые вы упомянули. Словарь по существу проверяет наличие в памяти отдельных значений. Выполнение DataTable.Select без индексов, использование LINQ to Datasets или to Objects, по сути, то же самое, что сканирование всех записей массива или List <> на предмет определенного значения, потому что это то, что делают все эти методы - сканировать весь список последовательно.

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

Есть несколько вещей, которые вы можете попробовать, в зависимости от того, что вам нужно сделать:

  • Если вы ищете быстрый способ нарезки и нарезки данных, используйте существующий продукт, такой как функциональность PowerPivot в Excel 2010. PowerPivot загружает и сжимает МНОГИЕ миллионы строк в столбчатом формате в памяти и позволяет запрашивать ваши данные, как если бы вы работали с сводной таблицей, и даже определяйте соединения с другими источниками в памяти.
  • Если вы хотите более повторяемый процесс, вы можете либо создать соответствующие звездообразные схемы в реляционной базе данных, либо использовать столбчатую базу данных. В любом случае вам придется написать сценарии для загрузки ваших данных в соответствующих структурах.

  • Если вы создаете свое собственное приложение, вам действительно нужно исследовать различные алгоритмы и структуры, используемые другими аналогичными инструментами, либо в памяти.

...