
У меня есть таблица MyISAM, которая в настоящее время содержит около 54 миллионов записей и имеет размер 20 ГБ. При проектировании этой базы данных был сделан неудачный выбор. Я не профессионал в области баз данных, но поскольку в эту таблицу постоянно записываются данные и редко запрашиваются, похоже, InnoDB был бы лучшим выбором. Проблема в том, что эта таблица должна быть доступна для записи практически всегда. Одно из полей — это поле с меткой времени. Записи хранятся 5 лет назад — мне нужно сохранить только последние 6 месяцев. Я пробовал некоторые удаления, удаление 200 000 строк занимает около 20 минут, в течение которых таблица заблокирована и в нее нельзя записывать данные. Есть ли у кого-нибудь предложения, как уменьшить размер этой таблицы, не блокируя ее на несколько часов? Есть ли более быстрый способ удалить ненужные строки? Я никогда не преобразовывал таблицу MyISAM в таблицу InnoDB. Это длительный процесс?
решение1
Наконец-то у меня появилось время вернуться к этому проекту, и для полноты картины я хотел бы опубликовать то, что я в итоге сделал. Первоначальная проблема с DELETE FROM, которая так долго выполнялась, как я полагаю, связана с тем, как я указывал строки для удаления. Я использовал оператор, похожий на
DELETE FROM table WHERE starttime < 20150101 limit 200000;
Поле starttime на самом деле DATETIME. Я в итоге создал новую таблицу, используя
CREATE TABLE new_table LIKE existing_table;
а затем изменение движка новой таблицы
ALTER TABLE new_table ENGINE=InnoDB;
а затем переименование
RENAME TABLE existing_table TO old_table, new_table TO existing_table;
После этого мне нужно было перенести данные за 6 месяцев из старой таблицы в новую.
INSERT INTO existing_table SELECT * FROM old_table WHERE starttime BETWEEN DATE_SUB(NOW(), INTERVAL 6 MONTH) AND NOW();
Спасибо, Мартин, за предложение. Я новичок на serverfault, поэтому не уверен, как отметить его комментарий как ответ.
решение2
MyISAM подходит только для SELECT. Innodb имеет отдельные очереди READ и WRITE. Поэтому при удалении 200 000 строк таблицы не будут заблокированы. Блокировки таблиц — одно из главных ограничений MyISAM, когда дело доходит до производства. InnoDB медленнее MyISAM для большинства применений, но может работать быстрее в определенных условиях благодаря лучшему механизму блокировки; MyISAM блокирует всю таблицу для чтения, пока выполняются вставки/обновления. InnoDB может выполнять блокировку на уровне строк, что позволяет выполнять несколько одновременных операций записи и чтения в таблице.
http://kakadba.blogspot.in/2014/02/innodb-vs-myisam.html
Преобразование MyISAM в INNODB
Вы можете сделать это таблица за таблицей.
ALTER TABLE table_name ENGINE=InnoDB;
Или вы можете попробовать скрипт, чтобы сделать все это сразу.
https://stackoverflow.com/questions/3856435/как-конвертировать-все-таблицы-из-myisam-в-innodb