2010-03-05 2 views
3

У меня есть таблица с 200 000 записей. я хочу, чтобы добавить поле к нему:MySQL: добавьте поле в большую таблицу

ALTER TABLE `table` ADD `param_21` BOOL NOT NULL COMMENT 'about the field' AFTER `param_20` 

но мне кажется, очень тяжелый запрос, и это занимает очень много времени, даже на моих Quad драмы ПК с 4 Гб оперативной памяти.

Я бегу под окнами/xampp и phpMyAdmin. действительно ли mysql имеет дело с каждой записью при добавлении поля? или я могу изменить запрос, чтобы он быстрее менял настройки?

+0

Рассмотрим настройку innodb_log_file_size (но будьте осторожны, см. Http://www.mysqlperformanceblog.com/2011/07/09/how-to-change-innodb_log_file_size-safely/) и innodb_log_buffer_size. Для получения дополнительной информации см. Мой ответ здесь: http://stackoverflow.com/a/12688184/1148030 –

ответ

5

MySQL почти во всех случаях перестраивает таблицу во время ALTER **. Это связано с тем, что двигатели на основе строк (т. Е. Все из них) должны сделать это, чтобы сохранить данные в правильном формате для запросов. Это также потому, что вы можете внести много других изменений, которые также потребуют перестройки таблицы (например, изменение индексов, первичных ключей и т. Д.)

Я не знаю, какой движок вы используете, но я буду предполагать MyISAM. MyISAM копирует файл данных, внося необходимые изменения в формат - это относительно быстро и вряд ли займет гораздо больше времени, чем оборудование IO может получить старый файл данных, а новый - на диск.

Восстановление индексов на самом деле является убийцей. В зависимости от того, как вы его настроили, MySQL будет либо: для каждого индекса помещать индексированные столбцы в буфер файлового сервера (который может быть в памяти, но обычно на диске), сортировать, используя свою функцию filesort() (которая делает quicksort путем рекурсивного копирования данных между двумя файлами, если он слишком велик для памяти), а затем построить весь индекс на основе отсортированных данных.

Если он не может выполнить трюк filesort, он будет вести себя так, как если бы вы вставляли INSERT в каждую строку, и по очереди заполняли индексные блоки данными каждой строки. Это очень медленно и приводит к далеким от оптимальных показателям.

Вы можете сказать, что он делает, используя SHOW PROCESSLIST во время процесса. «Ремонт с помощью filesort» хорош, «Ремонт с помощью keycache» - это плохо.

Все это будет использовать AT MOST одно ядро, но иногда может быть связано также с IO (особенно копирование файла данных).

** Есть некоторые исключения, такие как удаление вторичных индексов на таблицах плагинов innodb.

1

Вы добавляете столбец NOT NULL, кортежи необходимо заполнять. Так что это будет медленно ...

+0

привет, вы имеете в виду изменение NULL до NOT NULL с его решением? – Alexar

+0

Я попробовал. нет разницы. не решена. – Alexar

0

Это касается каждой из 200 000 записей, так как каждая запись должна быть обновлена ​​с новым значением bool, которое не будет равно нулю.

So; да, это дорогой запрос ... Нет ничего, что можно сделать, чтобы сделать его быстрее.

Смежные вопросы