MySQL: падение столбца из большой таблицы
Извините, если это ужасно очевидно, я MySQL noob.
У меня есть эта довольно большая таблица с тремя столбцами как таковой:
+-----+-----+----------+
| id1 | id2 | associd |
+-----+-----+----------+
| 1 | 38 | 73157604 |
| 1 | 112 | 73157605 |
| 1 | 113 | 73157606 |
| 1 | 198 | 31936810 |
| 1 | 391 | 73157607 |
+-----+-----+----------+
Это продолжается для строк в 38 м. Проблема в том, что я хочу удалить столбец "associd", но запуск ALTER TABLE table_name DROP COLUMN associd;
просто занимает слишком много времени. Я хотел сделать что-то вроде: ALTER TABLE table_name SET UNUSED associd;
и ALTER TABLE table_name DROP UNUSED COLUMNS CHECKPOINT 250;
, что, по-видимому, ускоряет процесс, но это невозможно в MySQL?
Есть ли альтернатива для удаления этого столбца - может быть, создать новую таблицу с двумя столбцами или получить падение с помощью контрольных точек? Спасибо!
Ответы
Ответ 1
Все, что вы делаете, потребует чтения и записи 38-метровых строк, поэтому ничего не будет очень быстро. Вероятно, самым быстрым методом, вероятно, является перенос данных в новую таблицу:
create table newTable as
select id1, id2
from oldTable;
Или, если вы хотите быть уверены, что сохраните типы и индексы:
create table newTable like oldTable;
alter table newTable drop column assocId;
insert into newTable(id1, id2)
select id1, id2
from oldTable;
Однако, как правило, быстрее отбрасывать весь индекс таблицы, прежде чем загружать кучу данных, а затем снова воссоздавать индексы.
Ответ 2
Отказ от ответственности: этот ответ ориентирован на MySQL и может не работать для других баз данных.
Я думаю, что в принятом ответе есть некоторые недостающие вещи, я попытался показать здесь общую последовательность, которую я использую для выполнения таких операций в рабочей среде, а не только для добавления/удаления столбцов, а также для добавления индексов для пример.
Мы называем это движение Индианы Джонса.
Создать новую таблицу
Новая таблица с использованием старого в качестве шаблона:
create table my_table_new like my_table;
Удалить столбец в новой таблице
В новой таблице:
alter table my_table_new drop column column_to_delete;
Добавить внешние ключи в новую таблицу
Не генерируются автоматически в команде create table like
.
Вы можете проверить фактические внешние ключи:
mysql> show create table my_table;
Затем примените их к новой таблице:
alter table my_table_new
add constraint my_table_fk_1 foreign key (field_1) references other_table_1 (id),
add constraint my_table_fk_2 foreign key (field_2) references other_table_2 (id)
Клонировать таблицу
Скопируйте все поля, кроме тех, которые хотите удалить.
Я использую предложение where
, чтобы иметь возможность запускать эту команду много раз, если это необходимо.
Как я полагаю, это производственная среда, my_table
будет иметь новые записи непрерывно, поэтому нам нужно продолжать синхронизацию, пока мы не сможем изменить имя.
Также я добавил limit
, потому что, если таблица слишком большая, а индексы слишком тяжелые, однократный клон может остановить производительность вашей базы данных. Кроме того, если в середине процесса вы хотите отменить операцию, он должен будет отменить все уже сделанные вставки, что означает, что ваша база данных не будет восстановлена мгновенно (https://dba.stackexchange.com/info/5654/internal-reason-for-killing-process-taking-up-long-time-in-mysql)
insert my_table_new select field_1, field_2, field_3 from my_table
where id > ifnull((select max(id) from my_table_new), 0)
limit 100000;
Как я делал это несколько раз, я создал процедуру: https://gist.github.com/fguillen/5abe87f922912709cd8b8a8a44553fe7
Смените имя с именем
Убедитесь, что вы сразу же запустили эти команды после репликации последних записей из своей таблицы. Idealy запускает все команды сразу.
rename table my_table to my_table_3;
rename table my_table_new to my_table;
Удалить старую таблицу
Убедитесь, что у вас есть резервная копия, прежде чем вы это сделаете;)
drop table my_table_3
Отказ от ответственности: я не уверен, что произойдет с внешними ключами, указывающими на старую таблицу.