it-roy-ru.com

ALTER TABLE ADD COLUMN занимает много времени

Я просто пытался добавить столбец с именем "location" к таблице (main_table) в базе данных. Команда, которую я запускаю, была

ALTER TABLE main_table ADD COLUMN location varchar (256);

Main_table содержит> 2 000 000 строк. Он продолжает работать более 2 часов и до сих пор не завершен. 

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

57
fanchyna

Ваш оператор ALTER TABLE подразумевает, что mysql должен будет переписать каждую строку таблицы, включая новый столбец. Поскольку у вас более 2 миллионов строк, я определенно ожидал бы, что это займет значительное количество времени, в течение которого ваш сервер, скорее всего, будет в основном связан с вводом-выводом. Вы обычно находите более эффективным делать следующее:

CREATE TABLE main_table_new LIKE main_table;
ALTER TABLE main_table_new ADD COLUMN location varchar(256);
INSERT INTO main_table_new (fields_in_main_table) SELECT * FROM main_table;
RENAME TABLE main_table TO main_table_old, main_table_new TO main_table;
DROP TABLE main_table_old;

Таким образом, вы добавляете столбец в пустую таблицу и в основном записываете в эту новую таблицу данные, которые, как вы уверены, никто больше не будет просматривать, не блокируя столько ресурсов.

163
Romain

Я думаю, что подходящий ответ для этого - использовать такую ​​функцию, как pt-online-schema-change или gh-ost

Благодаря этому мы выполнили миграцию более 4 миллиардов строк, хотя это может занять до 10 дней с минимальным временем простоя. 

Перкона работает очень похожим образом, как указано выше

  • Создать временную таблицу
  • Создает триггеры в первой таблице (для вставок, обновлений, удалений), чтобы они реплицировались во временную таблицу
  • В небольших партиях переносите данные
  • Когда закончите, переименуйте таблицу в новую таблицу и удалите другую таблицу
21
Pratik Bothra

Изменение таблицы занимает много времени с большими данными, как в вашем случае, поэтому избегайте использовать их в таких ситуациях и используйте некоторый код, подобный этому:

select main_table.*, 
  cast(null as varchar(256)) as null_location, -- any column you want accepts null
  cast('' as varchar(256)) as not_null_location, --any column doesn't accept null
  cast(0 as int) as not_null_int, -- int column doesn't accept null
into new_table 
from main_table;

drop table main_table;
rename table new_table TO main_table;
0
ZORRO_BLANCO