MySQL очень медленный для запроса альтернативной таблицы

Почему требуется больше часа, чтобы просто обновить эту таблицу, чтобы добавить столбец? Эта таблица имеет 15M строк. Он имеет 2 индекса и один ключевой первичный ключ. Запрос ALTER TABLE находился в состоянии "копировать в таблицу tmp" в течение 1 часа 15 минут.

ALTER TABLE `frugg`.`item_catalog_map` 
ADD COLUMN `conversion_url` TEXT NULL DEFAULT NULL

Таблица:

mysql> describe item_catalog_map;
+------------------------+---------------+------+-----+---------+-------+
| Field                  | Type          | Null | Key | Default | Extra |
+------------------------+---------------+------+-----+---------+-------+
| catalog_unique_item_id | varchar(255)  | NO   | PRI | NULL    |       |
| catalog_id             | int(11)       | YES  | MUL | NULL    |       |
| item_id                | int(11)       | YES  | MUL | NULL    |       |
| price                  | decimal(10,2) | YES  |     | 0.00    |       |
+------------------------+---------------+------+-----+---------+-------+

mysql> show index from item_catalog_map;
+------------------+------------+----------------------+--------------+------------------------+-----------+-------------+----------+--------+------+------------+---------+
| Table            | Non_unique | Key_name             | Seq_in_index | Column_name            | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+------------------+------------+----------------------+--------------+------------------------+-----------+-------------+----------+--------+------+------------+---------+
| item_catalog_map |          0 | PRIMARY              |            1 | catalog_unique_item_id | A         |    15485115 |     NULL | NULL   |      | BTREE      |         |
| item_catalog_map |          1 | IDX_ACD6184FCC3C66FC |            1 | catalog_id             | A         |          18 |     NULL | NULL   | YES  | BTREE      |         |
| item_catalog_map |          1 | IDX_ACD6184F126F525E |            1 | item_id                | A         |    15485115 |     NULL | NULL   | YES  | BTREE      |         |
+------------------+------------+----------------------+--------------+------------------------+-----------+-------------+----------+--------+------+------------+---------+

Ответ 1

MySQL. Производительность ALTER TABLE может стать проблемой с очень большими таблицами. MySQL выполняет большинство изменений, сделав пустую таблицу с нужной новой структурой, вставив все данные из старой таблицы в новую и удалив старую таблицу. Это может занять очень много времени, особенно если у вас мало памяти, а таблица большая и имеет множество индексов. У многих людей есть опыт работы с операциями ALTER TABLE, которым потребовалось несколько часов или дней.

Ответ 2

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

Еще две подсказки:

  • Прежде чем применять изменения индекса, выполните два следующих оператора и измените значения на 1 после завершения изменения индекса.

    SET unique_checks=0;
    SET foreign_key_checks=0;
    
  • При создании нескольких вторичных индексов помещайте их в один оператор ALTER TABLE, а не в несколько разделенных операторов ALTER TABLE.

На следующем рисунке показана разница в производительности. Подход 1 - ваш подход и подход 2 - мой путь. Подход 2 занимает около 3,47% времени по сравнению с подходом 1 для таблицы в 50 м. Решение работает только для MySQL ( >= 5.5) двигателя InnoDB.

enter image description here

Ответ 3

В вашей таблице есть 15 миллионов строк, что и есть. ALTER TABLE включает в себя копирование по всем данным из таблицы и воссоздание индексов. В качестве первого измерения попробуйте скопировать файл данных (item_catalog_map.MYD, если это MyISAM) в вашу файловую систему, и посмотреть, сколько времени это займет. Это время, когда ALTER TABLE, по крайней мере, займет.

Ответ 4

Инструменты Percona - это спасатель для этого материала с большими таблицами.

http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html

они в основном:

  • создать повторяющуюся таблицу
  • создать триггер для синхронизации таблиц
  • объемные копии данных
  • проверить
  • таблицы подкачки

Принимает навсегда, но кто заботится, потому что это означает, что вы можете менять столбцы без простоя.

Ответ 5

Чтобы свести к минимуму блокировку большой таблицы, которую я хочу изменить, я делаю следующее:

  • Создайте новую пустую таблицу на основе существующей таблицы и измените эту новую пустую таблицу.
  • Сделайте mysqldump большой таблицы таким образом, чтобы она содержала один полный оператор insert для записи в большой таблице (переключатели -c и -skip-extended-insert)
  • Импортируйте этот mysqldump в другую (пустую) базу данных с пустой переименованной большой_таблицей.
  • Возьмите mysqldump этой новой таблицы переименований из другой базы данных и импортируйте ее в исходную базу данных
  • Переименуйте large_table и large_table_new в исходную базу данных.

    mysql> create table DATABASE_NAME.LARGE_TABLE_NEW like DATABASE_NAME.LARGE_TABLE;
    mysql> alter table DATABASE_NAME.LARGE_TABLE_NEW add column NEW_COLUMN_NAME COL_DATA_TYPE(SIZE) default null;
    
    $ mysqldump -c --no-create-info --skip-extended-insert --no-create-db -u root -p DATABASE_NAME LARGE_TABLE > LARGE_TABLE.sql
    
    mysql> create table test.LARGE_TABLE like DATABASE_NAME.LARGE_TABLE;
    
    $ mysql -u root -p -D test < LARGE_TABLE.sql
    
    mysql> rename table test.LARGE_TABLE to test.LARGE_TABLE_NEW;
    
    $ mysqldump -c --no-create-info --skip-extended-insert --no-create-db -u root -p test LARGE_TABLE_NEW > LARGE_TABLE_NEW.sql
    
    $ mysql -u root -p -D DATABASE_NAME < LARGE_TABLE_NEW.sql
    
    mysql> rename table DATABASE_NAME.LARGE_TABLE to DATABASE_NAME.LARGE_TABLE_OLD, DATABASE_NAME.LARGE_TABLE_NEW to DATABASE_NAME.LARGE_TABLE;
    

Ответ 6

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