Как обрабатывать большие таблицы в MySQL? - PullRequest
10 голосов
/ 24 мая 2010

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

CREATE TABLE `item_property` (
    `property_id` int(11) NOT NULL,
    `item_id` int(11) NOT NULL,
    `value` double NOT NULL,
    PRIMARY KEY  (`property_id`,`item_id`),
    KEY `item_id` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Эта база данных имеет две цели: хранение (которое имеет первый приоритет и должно быть очень быстрым).Я хотел бы выполнить много вставок (сотен) за несколько секунд), извлекая данные (выбирает с помощью item_id и property_id) (это второй приоритет, он может быть медленнее, но не слишком много, потому что это разрушит мое использование БД).

В настоящее время эта таблица содержит 1,6 миллиарда записей, и простой подсчет может занять до 2 минут ... Вставка не достаточно быстра, чтобы ее можно было использовать.

Я использую Zend_Db для доступамои данные, и я был бы рад, если бы вы не предложили мне разработать какой-либо элемент стороны PHP.

Ответы [ 7 ]

10 голосов
/ 24 мая 2010

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

  • Настройка движка MyISAM-хранилища
  • Использовать "ЗАГРУЗИТЬ ДАННЫЕ INFILE filename INTO TABLE tablename"
  • Разделите ваши данные по нескольким таблицам

Вот и все. Остальное читайте, только если вас интересуют подробности:)

Все еще читаете? Хорошо, тогда вот что: MyISAM является краеугольным камнем, поскольку это самый быстрый двигатель на сегодняшний день. Вместо того, чтобы вставлять строки данных с помощью обычных операторов SQL, вы должны объединить их в файл и вставлять этот файл через равные промежутки времени (так часто, как вам нужно, но лучше всего, как позволяет ваше приложение). , Таким образом, вы можете вставить порядка миллиона строк в минуту.

Следующее, что ограничит вас, это ваши ключи / индексы. Когда они не помещаются в вашей памяти (потому что они просто слишком велики), вы будете испытывать огромное замедление как во вставках, так и в запросах. Вот почему вы разделяете данные на несколько таблиц, все по одной схеме. Каждая таблица должна быть настолько большой, насколько это возможно, без заполнения памяти при загрузке по одному. Конечно, точный размер зависит от вашей машины и индексов, но должен быть где-то между 5 и 50 миллионами строк / таблицей. Вы найдете это, если просто измерите время, необходимое для вставки огромного ряда строк за другим, в поисках момента, когда он значительно замедлится. Когда вы знаете предел, создавайте новую таблицу на лету каждый раз, когда ваша последняя таблица приближается к этому пределу.

Следствием многофункционального решения является то, что вам придется запрашивать все ваши таблицы, а не только одну, когда вам нужны какие-то данные, что немного замедлит ваши запросы (но не слишком сильно, если вы только) "есть миллиард или около того строк). Очевидно, что здесь есть и оптимизации. Если есть что-то фундаментальное, что вы можете использовать для разделения данных (например, дата, клиент или что-то еще), вы можете разделить это на разные таблицы, используя некоторый структурированный шаблон, который позволяет вам знать, где находятся определенные типы данных, даже не запрашивая таблицы. Используйте эти знания только для запросов к таблицам, которые могут содержать запрошенные данные и т. Д.

Если вам нужно еще больше настройки, перейдите на разбиение , как предложено Eineki и oedo.

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

0 голосов
/ 24 мая 2010

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

0 голосов
/ 24 мая 2010

Рассматривали ли вы вариант разбиение таблицы?

0 голосов
/ 24 мая 2010

Во-первых: одна таблица с 1,6 миллиардами записей кажется слишком большой.Я работаю на некоторых системах с довольно высокой нагрузкой, где даже таблицы журналов, которые отслеживают все действия, не становятся такими большими за последние годы.Поэтому, если возможно, подумайте, сможете ли вы найти более оптимальный способ хранения.Не могу дать гораздо больше советов, так как я не знаю вашу структуру БД, но я уверен, что будет много места для оптимизации.1,6 миллиарда записей - это слишком много.

Несколько факторов по производительности:

Если вам не нужны проверки целостности ссылок, что маловероятно, вы можете переключиться на механизм хранения MyISAM.Это немного быстрее, но в нем отсутствуют проверки целостности и транзакции.

Для чего-либо еще потребуется дополнительная информация.

0 голосов
/ 24 мая 2010

Загляните в memcache, чтобы увидеть, где его можно применить. Также обратите внимание на горизонтальное разбиение, чтобы уменьшить размеры таблиц / индексов.

0 голосов
/ 24 мая 2010

вау, это довольно большой стол:)

если вам нужно быстрое хранение, вы можете объединить вставки и вставить их с помощью одного оператора INSERT. однако, это определенно потребует дополнительного клиентского (php) кода, извините!

INSERT INTO `table` (`col1`, `col2`) VALUES (1, 2), (3, 4), (5, 6)...

также отключите все индексы, которые вам НЕ НУЖНЫ, так как индексы замедляют команды вставки.

в качестве альтернативы вы можете посмотреть на разбиение таблицы: linky

0 голосов
/ 24 мая 2010

Прежде всего, не используйте InnoDb, поскольку вам, похоже, не нужна его основная функция над MyISAM (блокировка, транзакция и т. Д.).Так что используйте MyISAM, это уже будет иметь какое-то значение.Тогда, если это все еще не достаточно быстро, начните индексирование, но вы уже должны увидеть радикальную разницу.

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