У меня есть таблица InnoDB, которую я хочу изменить. Таблица содержит ~ 80 миллионов строк и выходит из нескольких индексов.
Я хочу изменить имя одного из столбцов и добавить еще несколько индексов.
- Какой самый быстрый способ сделать это (при условии, что я могу страдать даже из-за простоя - сервер не используется)?
- Является ли «простой»
alter table
, самое быстрое решение?
В настоящее время меня волнует только скорость :)
SHOW CREATE TABLE tblname\G
, покажите столбец, который необходимо изменить, тип данных столбца и новое имя столбца.sent_at
и добавить к нему еще несколько индексовОтветы:
Один верный способ ускорить ALTER TABLE - удалить ненужные индексы
Вот начальные шаги для загрузки новой версии таблицы
Пожалуйста, обратите внимание на следующее:
Я удалил source_persona_index, потому что это первый столбец в 4 других индексах
Я удалил target_persona_index, потому что это первый столбец в 2 других индексах
Я удалил target_persona_relation_type_index, потому что первые 2 столбца также находятся в target_persona_relation_type_message_id_index
ОК Это заботится о ненужных индексах. Есть ли показатели, которые имеют низкую мощность? Вот способ определить это:
Запустите следующие запросы:
По твоему вопросу там около 80 000 000 строк. Как показывает практика, MySQL Query Optimizer не будет использовать индекс, если количество элементов в выбранных столбцах превышает 5% от числа строк таблицы. В этом случае это будет 4 000 000.
COUNT(DISTINCT sent_at)
> 4 000 000ALTER TABLE s_relations_new DROP INDEX sent_at_index;
COUNT(DISTINCT message_id)
> 4 000 000ALTER TABLE s_relations_new DROP INDEX message_id_index;
COUNT(DISTINCT target_object_id)
> 4 000 000ALTER TABLE s_relations_new DROP INDEX target_object_index;
После определения полезности или бесполезности этих индексов вы можете перезагрузить данные
Вот так, верно? НЕТ !!!
Если ваш сайт работал все это время, возможно, во время загрузки s_relations_new могут выполняться команды INSERT для s_relations. Как вы можете восстановить эти пропущенные строки?
Найдите максимальный идентификатор в s_relations_new и добавьте все после этого идентификатора из s_relations. Чтобы убедиться, что таблица заморожена и используется только для этого обновления, у вас должно быть небольшое время простоя ради получения тех последних строк, которые были вставлены в s_relation_new. Вот что ты делаешь:
В ОС перезапустите mysql, чтобы никто другой не мог войти в систему, кроме root @ localhost (отключает TCP / IP):
Затем войдите в MySQL и загрузите последние строки:
Затем перезапустите MySQL нормально
Теперь, если вы не можете избавиться от mysql, вам придется использовать s_relations. Просто войдите в MySQL и сделайте следующее:
Попробуйте!
ПРЕДОСТЕРЕЖЕНИЕ: Как только вы будете удовлетворены этой операцией, вы можете отказаться от старой таблицы при первой же возможности:
источник
Правильный ответ зависит от версии движка MySQL, который вы используете.
При использовании версии 5.6+ переименования и добавление / удаление индексов выполняются в режиме онлайн , т.е. без копирования всех данных таблицы.
Просто используйте
ALTER TABLE
как обычно, это будет в основном мгновенно для переименований и удаления индексов, и достаточно быстро для добавления индекса (так же быстро, как и чтение всей таблицы один раз).Если используется 5.1+, а плагин InnoDB включен, добавление / удаление индексов также будет онлайн. Не уверен насчет переименований.
Если вы используете старую версию,
ALTER TABLE
она по-прежнему самая быстрая, но, вероятно, будет ужасно медленной, потому что все ваши данные будут повторно вставлены во временную таблицу под капотом.Наконец, пришло время развенчать мифы. К сожалению, мне не хватает кармы, чтобы комментировать ответы, но я чувствую, что важно исправить наиболее проголосовавший ответ. Это неправильно :
На самом деле все наоборот .
Индексы полезны для выбора нескольких строк, поэтому важно, чтобы они имели большую мощность, что означает много разных значений и статистически мало строк с одинаковым значением.
источник
RENAME TABLE
мгновенный (как и ожидалось), ноCHANGE COLUMN
переименовать первичный ключ сделал полную копию ... 7 часов! Возможно, только потому, что это был первичный ключ? Фигово.У меня была такая же проблема с Maria DB 10.1.12, затем, прочитав документацию, я обнаружил, что есть возможность выполнить операцию «на месте», которая исключает копию таблицы. С этой опцией таблица изменения очень быстрая. В моем случае это было:
это очень быстро Без опции алгоритма он никогда не закончится.
https://mariadb.com/kb/en/mariadb/alter-table/
источник
Для переименования столбца
должно быть хорошо и не иметь никакого простоя.
Для индексов инструкция CREATE INDEX заблокирует таблицу. Если это неиспользованный раб, как вы упомянули, это не проблема.
Еще один вариант - создать новую таблицу с правильными именами столбцов и индексами. Затем вы можете скопировать все данные в него, а затем выполнить серию
Это минимизирует время простоя за счет временного использования в два раза больше места.
источник
У меня тоже есть эта проблема, и я использовал этот SQL:
Я надеюсь, что это может помочь кому-то
С Уважением,
Будет
источник