2013-10-05 2 views
2

Рассмотрим следующую таблицу:MySQL Partitioning: SELECT по идентификатору, но УДАЛИТЬ по дате

CREATE TABLE `event` (
    `uid` bigint(13) NOT NULL, 
    `time` bigint(14) NOT NULL, 
    `type` smallint(5) NOT NULL, 
    `msg` varchar(2048) DEFAULT NULL, 
    KEY `uid` (`uid`), 
    KEY `time` (`time`), 
    KEY `time_type_uid` (`time`,`type`,`uid`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

Что я в принципе сделать:

  • INSERT ~ 1 миллион строк в день, текущий размер составляет около 100 миллион записей
  • DELETE все строки старше 100 дней:
    • Заявление # 1: DELETE FROM event WHERE time < unix_timestamp() - 100 * 86400;
    • Ведомость № 2: DELETE FROM event WHERE time < unix_timestamp() - 100 * 86400 LIMIT 1000;
  • Пользователи будут SELECT все события по UID, около 500 запросов в день в сумме, так не то, что довольно много:
    • Заявление # 1: SELECT * FROM event WHERE uid = 4711 И type В (23,1002,12, 1);
    • Ведомость № 2: SELECT * FROM event WHERE uid = 4711 И type IN (23,1002,12,1) И time BETWEEN 1381051061 AND 1381051861;

Обработка этой таблицы стали довольно медленно, особенно после DELETE блоков заданий INSERT с/SELECT сек на столе. Мы пробовали ежедневный объем DELETE, как объяснялось выше (Statement # 1), который больше не работает без блокировки таблицы. В настоящее время мы удаляем каждые 30 секунд (Statement # 2), но это будет блокироваться в течение 10 секунд.

Мы планируем увеличить нагрузку INSERT, но первые тесты приводят к зависанию резьбы в состоянии «Системный блок», я думаю, это связано с I/O. Настройки сервера оптимизируются, как предложено mysqltuner.pl. Аппаратная система имеет определенные проблемы ввода-вывода и «как есть», к сожалению, она не может быть изменена по нескольким причинам. У нас даже нет доступа root.

Является ли разделение даже решением и является MyISAM лучшим двигателем для использования? Перед улучшением аппаратного обеспечения нам необходимо оптимизировать все, что угодно.

+0

Голосование, чтобы закрыть: слишком широко. Увлекательная проблема, но слишком широкая для окончательного ответа здесь, и, возможно, не проблема программирования. Мы можем рассказать вам, как разделять, но мы не можем оптимизировать абстрактные. Почему не InnoDB? Каковы настройки сервера? Что такое системные спецификации и загрузка? Какие еще запросы выполняются? Как часто вы удаляете, и может ли это быть более частым? У вас есть правильные индексы для вашего шаблона запроса? (Мое предположение, не совсем.) И т.д. – pilcrow

+0

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

+0

dba.stackexchange может быть лучшим местом, чтобы спросить, какие виды оптимизации подходят и как вы оцениваете их эффективность. – pilcrow

ответ

0

Просто используйте InnoDB with snapshot isolation для получения читаемого моментального снимка. Таким образом, ваши большие удаленные задания не блокируются. Я не думаю, что вы должны перейти к разделению для этой довольно стандартной ситуации. Разделение является большим молотом и инвазивным. Возможно, достаточно простых мер.

0

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

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

Попробуйте запустить

DELETE FROM event 
      WHERE TIME < < unix_timestamp()-100*86400 
     LIMIT 10000 

снова и снова. Это уменьшит время, в течение которого каждая операция DELETE блокирует вашу таблицу и освобождает ее для других операций.

Укажите, есть ли у вас правильный составной индекс (время, тип, uid). Запросы, которые вы нам показали, не используют этот индекс, а индексы занимают время, когда вы вставляете. Похоже, вы можете просто удалить этот индекс. Возможно, вам понадобится индекс (uid, type) для указанного вами запроса.

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

Можете ли вы позволить себе ежедневные или еженедельные простоя? Если это так, используйте

OPTIMIZE NO_WRITE_TO_BINLOG TABLE event 

раз в то время, чтобы убрать таблицы и структуры индексов.

+0

Спасибо, мы уже пробовали удалить с лимитом. Он работает, но блокируется около 10 секунд. Определенно не будет работать с большим количеством INSERT одновременно. –

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