база данных для аналитики - PullRequest
3 голосов
/ 03 апреля 2009

Я настраиваю большую базу данных, которая будет генерировать статистические отчеты из входящих данных.
Система будет в основном работать следующим образом:

  1. Приблизительно 400–500 тыс. Строк - около 30 столбцов, в основном varchar (5–30) и datetime - будут загружаться каждое утро. Его размер составляет около 60 МБ в виде плоского файла, но в БД он резко увеличивается с добавлением подходящих индексов.
  2. Различные данные будут генерироваться из данных текущего дня.
  3. Отчеты из этой статистики будут создаваться и храниться.
  4. Текущий набор данных будет скопирован в таблицу многораздельной истории.
  5. В течение дня конечный пользователь может запрашивать текущий набор данных (который был скопирован, но не перемещен) для получения информации, которая вряд ли будет включать константы, но отношения между полями.
  6. Пользователи могут запрашивать специализированные поиски из таблицы истории, но запросы будут обработаны администратором базы данных.
  7. Перед загрузкой на следующий день текущая таблица данных усекается.

По сути, это будет версия 2 нашей существующей системы.

Прямо сейчас мы используем MyISAM-таблицы MySQL 5.0 (Innodb убивал только из-за использования пространства) и сильно страдаем на # 6 и # 4. # 4 в настоящее время не является секционированной таблицей, так как 5.0 не поддерживает ее. Чтобы обойти огромное количество времени (часы и часы), которое требуется для вставки записей в историю, мы пишем каждый день в неиндексированную таблицу history_queue, а затем по выходным в наше самое медленное время записываем очередь в таблица истории. Проблема в том, что любые исторические запросы, сгенерированные на этой неделе, возможно, отстают на несколько дней. Мы не можем уменьшить индексы для хронологической таблицы или ее запросы станут непригодными для использования.

Мы определенно переходим по крайней мере к MySQL 5.1 (если мы останемся с MySQL) для следующего выпуска, но настоятельно рекомендуем PostgreSQL. Я знаю, что дебаты были проведены до смерти, но мне было интересно, есть ли у кого-нибудь какие-либо советы, относящиеся к этой ситуации. Большая часть исследований вращается вокруг использования веб-сайта. Индексирование - это наша главная проблема с MySQL, и кажется, что PostgreSQL может помочь нам с помощью частичных индексов и индексов, основанных на функциях.

Я читал десятки статей о различиях между ними, но большинство из них старые. PostgreSQL уже давно называют «более продвинутым, но медленным» - это все еще обычно случай сравнения MySQL 5.1 с PostgreSQL 8.3 или более сбалансированный сейчас?

Коммерческие базы данных (Oracle и MS SQL) просто не подходят, хотя я бы хотел, чтобы Oracle был.

Примечание по MyISAM vs Innodb для нас: Мы работали с Innodb, и мы обнаружили, что он НАМНОГО медленнее, примерно в 3-4 раза медленнее. НО, мы также были намного новее с MySQL, и, честно говоря, я не уверен, что мы настроили db для Innodb.

Мы работаем в среде с очень высокой степенью бесперебойной работы - резервное копирование батареи, резервные сетевые подключения, резервные генераторы, системы с полным резервированием и т. Д. Таким образом, проблемы целостности с MyISAM были взвешены и признаны приемлемыми.

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

Что касается PostgreSQL: COUNT (*) без условия where - довольно редкий случай для нас. Я не ожидаю, что это будет проблемой. COPY FROM не так гибок, как LOAD DATA INFILE, но промежуточная таблица загрузки исправит это.Больше всего меня беспокоит отсутствие INSERT IGNORE. Мы часто использовали его при построении некоторой таблицы обработки, чтобы избежать дублирования нескольких записей, а затем выполнить гигантский GROUP BY в конце, чтобы удалить некоторые ошибки. Я думаю, что его использовали достаточно редко, чтобы его не было терпимым.

Ответы [ 9 ]

2 голосов
/ 04 апреля 2009

Моя работа пробовала пилотный проект для переноса исторических данных из настроек ERP. Размер данных небольшой, всего 60 Гбайт, охватывающий более 21 миллиона строк, самая большая таблица содержит 16 миллионов строк. Есть еще ~ 15 миллионов строк, ожидающих входа в трубу, но пилот был отложен из-за других приоритетов. План состоял в том, чтобы использовать средство «Задание» в PostgreSQL для планирования запросов, которые ежедневно генерировали бы данные, пригодные для использования в аналитике.

Запуск простых агрегатов по большой 16-миллионной таблице записей, первое, что я заметил, - насколько она чувствительна к объему доступной оперативной памяти. В какой-то момент увеличение оперативной памяти позволило собрать агрегаты за год, не прибегая к последовательному сканированию таблиц.

Если вы решите использовать PostgreSQL, я настоятельно рекомендую перенастроить файл конфигурации, так как он обычно поставляется с наиболее консервативными настройками (так что он будет работать в системах с небольшим объемом ОЗУ). Настройка занимает немного, может быть, несколько часов, но как только вы дойдете до точки, где ответ будет приемлемым, просто установите его и забудьте об этом.

Как только вы закончите настройку на стороне сервера (и все дело в памяти, сюрприз!), Вы переключитесь на свои индексы. Индексация и планирование запросов также требуют небольших усилий, но после настройки вы обнаружите, что они эффективны. Частичные индексы - хорошая функция для выделения тех записей, в которых есть данные «крайнего регистра», я настоятельно рекомендую эту функцию, если вы ищете исключения в море похожих данных.

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

2 голосов
/ 03 апреля 2009

Из моего практического опыта я должен сказать, что у postgresql был довольно резкий скачок производительности с 7.x / 8.0 до 8.1 (для наших случаев использования в некоторых случаях в 2x-3x быстрее), с 8.1 до 8.2 улучшение было меньше, но все еще заметно. Я не знаю улучшений между 8.2 и 8.3, но я ожидаю, что есть некоторое улучшение производительности, я пока не тестировал его.

Что касается индексов, я бы порекомендовал отбросить их и создавать их снова только после заполнения базы данных вашими данными, это намного быстрее.

Дальнейшее улучшение дерьма из ваших настроек postgresql, от него так много пользы. Настройки по умолчанию, по крайней мере, разумны сейчас, в 8,2 раза pg был оптимизирован для работы на КПК.

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

Ах, да, я говорил, что вы должны пойти на postgresql?

(альтернативой может быть firebird, который не так гибок, но по моему опыту он в некоторых случаях работает намного лучше, чем mysql и postgresql)

1 голос
/ 04 апреля 2009

Люди из Infobright, кажется, делают некоторые интересные вещи по этим направлениям:

http://www.infobright.org/

- psj

1 голос
/ 03 апреля 2009

Я бы пошел на PostgreSQL. Например, вам нужны секционированные таблицы, которые находятся в стабильных выпусках Postgres как минимум с 2005 года - в MySQL это новинка. Я слышал о проблемах со стабильностью в новых функциях 5.1 . С MyISAM у вас нет ссылочной целостности, транзакции и одновременный доступ сильно страдают - читайте эту запись в блоге " Использование MyISAM в производстве " для получения дополнительной информации.

А Postgres намного быстрее справляется со сложными запросами, что будет полезно для вашего # 6. Существует также очень активный и полезный список рассылки , где вы можете бесплатно получить поддержку даже от разработчиков ядра Postgres . Хотя у него есть Гочас .

1 голос
/ 03 апреля 2009

Что мне не понятно, так это то, насколько сложна аналитическая обработка. По моему мнению, наличие 500K записей для обработки не должно быть такой большой проблемой, с точки зрения аналитической обработки, это небольшой набор записей.

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

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

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

1 голос
/ 03 апреля 2009

По моему опыту, Inodb немного быстрее для действительно простых запросов, pg для более сложных запросов. Myisam, вероятно, даже быстрее, чем Innodb для поиска, но, возможно, медленнее для индексации / восстановления индекса.

Это в основном поля varchar, индексируете ли вы их с помощью char (n) индексов?

Можете ли вы нормализовать некоторые из них? Это будет стоить вам переписать, но может сэкономить время на последующих запросах, так как ваш размер строки уменьшится, что позволит разместить больше строк в памяти за один раз.

В режиме редактирования:

Хорошо, у вас есть две проблемы: время запроса к ежедневному и обновление истории, да?

Что касается второго: по моему опыту, MySQL плохо работает при переиндексации. В таблицах размером с ваши ежедневные записи (от 0,5 до 1 млн. Записей, с довольно широкими (денормализованными плоскими входными данными) записями) я обнаружил, что быстрее переписать таблицу, чем вставлять и ждать повторной индексации и перебивания сопутствующего диска.

Так что может или может не помочь:

create new_table select * from old_table ;

копирует таблицы, но без индексов.

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

Редактировать: В ответ на четвертый комментарий: я не знаю, что MyIsam всегда так плохо. Я знаю, что в моем конкретном случае я был шокирован тем, насколько быстрее было копирование таблицы и добавление индекса. Как это случилось, я делал что-то похожее на то, что вы делали, копируя большие денормализованные плоские файлы в базу данных, а затем перенормировав данные. Но это анекдот, а не данные. ;)

(Я также думаю, что в целом InnoDb был быстрее, учитывая, что я выполнял столько же операций вставки, сколько и запросов. Очень особый случай использования базы данных.)

Обратите внимание, что копирование с использованием select a. *, B.value в качестве foo join ... также выполнялось быстрее, чем обновление a.foo = b.value ... join, которое следует, так как обновление было внесено в индексированный колонка.

0 голосов
/ 03 мая 2011

Вы пробовали играть с параметром myisam_key_buffer? Это очень важно для скорости обновления индекса.

Также, если у вас есть индексы по дате, идентификатору и т. Д., Которые являются коррелированными столбцами, вы можете сделать:

INSERT INTO archive SELECT .. FROM current ORDER BY id (or date)

Идея состоит в том, чтобы вставлять строки по порядку, в этом случае обновление индекса происходит намного быстрее. Конечно, это работает только для индексов, которые согласуются с ORDER BY ... Если у вас есть несколько довольно случайных столбцов, то это не поможет.

но строго учитывая PostgreSQL.

Вы обязательно должны проверить это.

похоже, что PostgreSQL может помочь нам с помощью частичных индексов и индексов, основанных на функциях.

Да.

Я читал десятки статей о различиях между ними, но большинство из них старые. PostgreSQL уже давно называли «более продвинутым, но медленным» - это все еще обычно случай сравнения MySQL 5.1 с PostgreSQL 8.3 или более сбалансированный сейчас?

Ну, это зависит. Как и в любой базе данных,

  • ЕСЛИ ВЫ НЕ ЗНАЕТЕ, КАК НАСТРОИТЬ И НАСТРОЙИТЬ, ЭТО БУДЕТ МЕДЛЕННО
  • Если ваше оборудование не соответствует задаче, оно будет медленным

Некоторые люди, которые хорошо знают mysql и хотят попробовать postgres, не учитывают тот факт, что им нужно заново изучать некоторые вещи и читать документы, в результате чего действительно плохо настроенный postgres тестируется, и это может быть довольно медленно.

Для использования в Интернете я провел сравнительный анализ хорошо сконфигурированных postgres на низкоуровневом сервере (Core 2 Duo, диск SATA) с настраиваемым тестовым форумом, который я написал, и он выдает более 4000 веб-страниц форума в секунду насыщение гигабитного Ethernet-соединения сервера базы данных. Так что, если вы знаете, как его использовать, он может кричать быстро (InnoDB был намного медленнее из-за проблем параллелизма). «MyISAM быстрее для небольших простых выборок» - это всего лишь бык, postgres запустит «небольшой простой выбор» за 50-100 микросекунд.

Теперь, для вашего использования, вас это не волнует;)

Вы заботитесь о том, как ваша база данных может вычислять большие агрегаты и большие объединения, и правильно сконфигурированные postgres с хорошей системой ввода-вывода обычно выигрывают у системы MySQL на них, потому что оптимизатор намного умнее и имеет гораздо больше соединений / агрегатные типы на выбор.

Больше всего меня беспокоит отсутствие INSERT IGNORE. Мы часто использовали его при построении некоторой таблицы обработки, чтобы избежать дублирования нескольких записей, а затем выполнить гигантский GROUP BY в конце, чтобы удалить некоторые ошибки. Я думаю, что его использовали достаточно редко, чтобы его было терпимо.

Вы можете использовать GROUP BY, но если вы хотите вставить в таблицу только записи, которых еще нет, вы можете сделать это:

INSERT INTO target SELECT .. FROM source LEFT JOIN target ON (...) WHERE target.id IS NULL

В вашем случае использования у вас нет проблем с параллелизмом, так что это хорошо работает.

0 голосов
/ 04 апреля 2009

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

Если у вас слишком много индексов, это существенно замедлит вставку.

Как дела со своими вставками? Если вы делаете одну запись на оператор INSERT:

INSERT INTO TABLE blah VALUES (?, ?, ?, ?)

и, если его назвать 500К раз, ваша производительность будет отстойной. Я удивлен, что это заканчивается через часы. С MySQL вы можете вставлять сотни или тысячи строк одновременно:

INSERT INTO TABLE blah VALUES
  (?, ?, ?, ?),
  (?, ?, ?, ?),
  (?, ?, ?, ?)

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

Также гораздо быстрее использовать LOAD DATA INFILE для импорта файла CSV. Смотри http://dev.mysql.com/doc/refman/5.1/en/load-data.html

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

EDIT

Если у вас возникают проблемы с пакетным импортом 500K записей, вам нужно пойти на компромисс. Я бы отбросил некоторые индексы в вашей главной таблице, а затем создал бы оптимизированные представления данных для каждого отчета.

0 голосов
/ 04 апреля 2009

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

...