Pourquoi faut-il plus d'une heure pour simplement mettre à jour ce tableau pour ajouter une colonne? Ce tableau comporte 15 millions de lignes. Il possède 2 index et une clé primaire à clé unique. La requête ALTER TABLE est à l'état "copie dans la table tmp" depuis 1 heure 15 minutes maintenant.
ALTER TABLE `frugg`.`item_catalog_map`
ADD COLUMN `conversion_url` TEXT NULL DEFAULT NULL
Table:
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 | |
+------------------+------------+----------------------+--------------+------------------------+-----------+-------------+----------+--------+------+------------+---------+
Les performances ALTER TABLE de MySQL peuvent devenir un problème avec les très grandes tables. MySQL effectue la plupart des modifications en créant une table vide avec la nouvelle structure souhaitée, en insérant toutes les données de l'ancienne table dans la nouvelle et en supprimant l'ancienne table. Cela peut prendre beaucoup de temps, surtout si vous manquez de mémoire et que la table est volumineuse et contient de nombreux index. De nombreuses personnes ont de l'expérience avec les opérations ALTER TABLE qui ont pris des heures ou des jours pour se terminer.
Quoi qu'il en soit, si vous devez continuer avec alter table, les ressources suivantes pourraient peut-être vous aider:
Si vous ne vous souciez pas des temps d'arrêt, ma suggestion utilise trois ALTER TABLE
déclarations. La première instruction supprime tous les index secondaires existants. La deuxième instruction applique toutes les modifications liées aux colonnes. La dernière instruction ajoute des index secondaires supprimés et applique d'autres modifications d'index.
Deux autres conseils:
Avant d'appliquer les modifications d'index, exécutez les deux instructions suivantes et remettez les valeurs à 1 après avoir terminé la modification d'index.
SET unique_checks=0;
SET foreign_key_checks=0;
Lorsque vous créez plusieurs index secondaires, placez-les dans un ALTER TABLE
instruction plutôt que plusieurs séparés ALTER TABLE
déclarations.
L'image suivante montre la différence de performances. L'approche 1 est votre approche et l'approche 2 est ma voie. L'approche 2 prend environ 3,47% de temps par rapport à l'approche 1 pour une table de 50 m. La solution ne fonctionne que pour le moteur InnoDB MySQL (> = 5,5).
Les outils Percona sont une bouée de sauvetage pour ce genre de choses avec de grandes tables.
http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html
ils ont essentiellement:
Cela prend une éternité, mais peu importe car cela signifie que vous pouvez modifier les colonnes sans interruption.
Votre table contient 15 millions de lignes, ce qui est quelque chose. ALTER TABLE implique la copie de toutes les données de la table et la recréation des index. Comme première mesure, essayez de copier le fichier de données (item_catalog_map.MYD si c'est MyISAM) dans votre système de fichiers et voyez combien de temps cela prend. C'est le temps que prendra ALTER TABLE au moins.
Pour minimiser le verrouillage de la grande table que je souhaite modifier, je fais ce qui suit:
Renommez large_table et large_table_new dans la base de données d'origine.
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;