2016-09-26 4 views
6

Извините за длинный пост!Обработка очень больших данных с помощью mysql

У меня есть база данных, содержащая ~ 30 таблиц (движок InnoDB). Только две из этих таблиц, а именно «транзакция» и «сдвиг», довольно велики (первая имеет 1,5 миллиона строк, а сдвиг - 23 тыс. Строк). Теперь все работает нормально, и у меня нет проблем с текущим размером базы данных.

Однако у нас будет аналогичная база данных (такие же типы данных, дизайн, ..), но гораздо больше, например, таблица «транзакция» будет иметь около 1 млрд записей (около 2,3 млн транзакций в день) и мы думаем о том, как мы должны иметь дело с таким объемом данных в MySQL? (это как чтение, так и запись). Я прочитал много связанных сообщений, чтобы узнать, может ли Mysql (и, более конкретно, движок InnoDB) хорошо работать с миллиардами записей, но все же у меня есть некоторые вопросы. Некоторые из этих связанных должностей, которые я прочитал в следующем:

Что я понял до сих пор, чтобы улучшить производительность для очень больших таблиц:

  1. (для таблиц InnoDB, которые мой случай), увеличивающий innodb_buffer_pool_size (например, до 80% оперативной памяти). Кроме того, я нашел некоторые другие параметры Тюнинг: производительность MySQL here in percona blog
  2. , имеющие соответствующие индексы на столе (используя EXPLAN по запросам)
  3. секционирования таблицы
  4. MySQL шардинге или кластеризация

Вот мои вопросы/confusions:

  • О разделении, у меня есть некоторые сомнения, следует ли использовать его или нет. С одной стороны, многие люди предложили улучшить производительность, когда таблица очень велика. С другой стороны, я прочитал много сообщений, в которых говорится, что они не улучшают производительность запросов и не ускоряют выполнение запросов (например, here и here). Кроме того, я прочитал в MySQL Reference Manual, что Внешние ключи InnoDB и разбиение MySQL не совместимы (у нас есть внешние ключи).

  • Что касается индексов, то сейчас они хорошо работают, но, насколько я понял, для очень больших таблиц индексация является более ограничительной (как сказал Кевин Беделл в своем ответе here). Кроме того, индексы ускоряют чтение при замедлении записи (вставка/обновление). Итак, для нового аналогичного проекта у нас будет эта большая БД, мы должны сначала вставить/загрузить все данные, а затем создать индексы? (для ускорения вставки)

  • Если мы не можем использовать разделение для нашей большой таблицы (таблица транзакций), что является альтернативным вариантом для повышения производительности? (кроме параметров переменной MySQl, таких как innodb_buffer_pool_size). Должны ли мы использовать кластеры Mysql?(У нас есть также много объединений)

EDIT

Это show create table заявление для нашего крупнейшего стола под названием "сделка":

CREATE TABLE `transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`terminal_transaction_id` int(11) NOT NULL, 
`fuel_terminal_id` int(11) NOT NULL, 
`fuel_terminal_serial` int(11) NOT NULL, 
`xboard_id` int(11) NOT NULL, 
`gas_station_id` int(11) NOT NULL, 
`operator_id` text NOT NULL, 
`shift_id` int(11) NOT NULL, 
`xboard_total_counter` int(11) NOT NULL, 
`fuel_type` int(11) NOT NULL, 
`start_fuel_time` int(11) NOT NULL, 
`end_fuel_time` int(11) DEFAULT NULL, 
`preset_amount` int(11) NOT NULL, 
`actual_amount` int(11) DEFAULT NULL, 
`fuel_cost` int(11) DEFAULT NULL, 
`payment_cost` int(11) DEFAULT NULL, 
`purchase_type` int(11) NOT NULL, 
`payment_ref_id` text, 
`unit_fuel_price` int(11) NOT NULL, 
`fuel_status_id` int(11) DEFAULT NULL, 
`fuel_mode_id` int(11) NOT NULL, 
`payment_result` int(11) NOT NULL, 
`card_pan` text, 
`state` int(11) DEFAULT NULL, 
`totalizer` int(11) NOT NULL DEFAULT '0', 
`shift_start_time` int(11) DEFAULT NULL, 
PRIMARY KEY (`id`), 
UNIQUE KEY `terminal_transaction_id` (`terminal_transaction_id`,`fuel_terminal_id`,`start_fuel_time`) USING BTREE, 
KEY `start_fuel_time_idx` (`start_fuel_time`), 
KEY `fuel_terminal_idx` (`fuel_terminal_id`), 
KEY `xboard_idx` (`xboard_id`), 
KEY `gas_station_id` (`gas_station_id`) USING BTREE, 
KEY `purchase_type` (`purchase_type`) USING BTREE, 
KEY `shift_start_time` (`shift_start_time`) USING BTREE, 
KEY `fuel_type` (`fuel_type`) USING BTREE 
) ENGINE=InnoDB AUTO_INCREMENT=1665335 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT 

Спасибо за ваше время,

+1

Хехе - «длинный пост» дает «длинный ответ». –

+2

Кокаин - препарат хеллувы. –

ответ

12
  • Может ли MySQL разумно выполнять запросы на миллиарды строк? - MySQL может обрабатывать миллиарды строк. «Разумно» зависит от запросов; посмотрим на них.

  • Является ли InnoDB (MySQL 5.5.8) правильным выбором для многомиллиардных рядов? - 5.7 имеет некоторые улучшения, но 5.5 неплохо, несмотря на то, что ему почти 6 лет, и на грани больше не поддерживается.

  • Лучшее хранилище данных для миллиардов строк. Если вы имеете в виду «Двигатель», то InnoDB.

  • Насколько велика может быть база данных MySQL до того, как производительность начнет ухудшаться - опять же, это зависит от запросов. Я могу показать вам таблицу строк в 1К, которая будет расплавляться; Я работал с миллиардными таблицами, которые гудят.

  • Почему MySQL может быть медленным с большими таблицами? - сканирование диапазона приводит к I/O, что является медленной частью.

  • Может ли Mysql обрабатывать столы, на которых будет храниться около 300 миллионов записей? - снова, да. Предел составляет около триллиона рядов.

  • (для таблиц innoDB, которые являются моим случаем), увеличивая innodb_buffer_pool_size (например, до 80% ОЗУ). Кроме того, я нашел некоторые настройки настройки производительности MySQL здесь, в блоге percona - да

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

  • Разделение стола - «Разделение не является панацеей!» Я твердить, что в my blog

  • MySQL сегментирование - В настоящее время это DIY

  • MySQL кластеризация - В настоящее время лучший ответ некоторые Галера на основе вариант (PXC, MariaDB 10, DIY ж/Oracle)

  • Разделение не поддерживает FOREIGN KEY или "global" UNIQUE.

  • UUIDs, в масштабе, о котором вы говорите, не только замедлит работу системы, но и фактически убьет ее. Type 1 UUIDs может быть обходным путем.

  • Вставка и скорость построения индекса. Существует слишком много вариантов, чтобы дать один ответ. Давайте посмотрим на ваш пример CREATE TABLE и как вы собираетесь подавать данные.

  • Множество соединений - «Нормализовать, но не перенастраивать». В частности, не нормализуйте datetimes или float или другие «непрерывные» значения.

  • ли построить summary tables

  • 2,3 млн транзакций в день - Если это 2,3 млн вставки (30/с), то есть не так много проблем с производительностью. Если более сложный, тогда может потребоваться RAID, SSD, пакетная обработка и т. Д.

  • сделка с таким объемом данных. Если большинство действий связано с «недавними» строками, то buffer_pool будет «кэшировать» активность, тем самым избегая ввода-вывода. Если активность «случайная», то MySQL (или у кого-то еще) будут иметь проблемы с вводом-выводом.

+0

Еще один пункт - «MySQL NDB Cluster» отличается от Galera; NDB имеет нишевый рынок; это _might_ будет полезно для вас; давайте посмотрим подробнее о вашем приложении. –

+0

Спасибо Рику за подробный ответ. Теперь моя главная забота заключается в том, что я не уверен, нужно ли делать кластеризацию или нет (я никогда не делал этого раньше). Я имею в виду, когда мы должны это делать, а когда не будем? какие факторы следует учитывать перед кластеризацией? и если мы должны это сделать, с чего начать? – mOna

+0

Также вы сказали, что должны видеть запросы (для индексирования, производительности, ..). Какую информацию о запросах я должен учитывать? какая информация о нашем приложении вам нужна? Как я могу показать вам запросы? (извините, если это глупый вопрос!) – mOna

2

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

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

+1

Я согласен. Это в основном делает то же самое количество обработки, но распространяется со временем, а не в одно и то же время. – Aeolun

Смежные вопросы