Вы должны подумать о своих требованиях немного более тщательно.
На самом простом уровне, самый быстрый способ изменить таблицу - это сделать как можно меньше ALTER TABLE
операторов, предпочтительно один. Это связано с тем, что MySQL копирует данные таблицы для изменения схемы и делает пятнадцать изменений, в то время как создание одной копии, очевидно (и действительно), быстрее, чем копирование таблицы пятнадцать раз, делая одно изменение за раз.
Но я подозреваю, что вы спрашиваете, как сделать это изменение с наименьшим количеством простоев. То, как я это сделаю, вы в основном синтезируете, как неблокированный ALTER TABLE
будет работать. Но у него есть некоторые дополнительные требования:
- вам нужен способ для отслеживания добавленных и измененных данных, например, с помощью «измененного» поля даты для последних или поля
AUTO_INCREMENT
для первых.
- вам нужно место, чтобы иметь две копии вашей таблицы в базе данных.
- вам нужен период времени, когда изменения таблицы не будут слишком далеко опережать моментальный снимок
Основная техника, как вы предложили, то есть использование INSERT INTO ... SELECT ...
. По крайней мере, вы впереди, потому что вы начинаете с таблицы InnoDB, поэтому SELECT
не будет блокироваться. Я рекомендую сделать ALTER TABLE
для новой пустой таблицы, что позволит MySQL снова скопировать все данные, что будет означать, что вам нужно правильно перечислить все поля в операторе INSERT INTO ... SELECT ...
. Затем вы можете сделать простой оператор RENAME
, чтобы поменять его местами. Затем вам нужно сделать еще INSERT INTO ... SELECT ... WHERE ...
и, возможно, UPDATE ... INNER JOIN ... WHERE ...
, чтобы получить все измененные данные. Вам нужно быстро INSERT
и UPDATE
, иначе ваш код начнет добавлять новые строки и обновления в ваш снимок, которые будут мешать вашему обновлению. (У вас не возникнет этой проблемы, если вы сможете перевести свое приложение в режим обслуживания на несколько минут до RENAME
.)
Кроме того, есть некоторые настройки, относящиеся к ключу и буферу, которые можно изменить всего за один сеанс, что может помочь перемещению основных данных. Такие вещи, как read_rnd_buffer_size
и read_buffer_size
были бы полезны для увеличения.