MySQL: ajouter un champ à une grande table
j'ai une table avec environ 200 000 enregistrements. je veux ajouter un champ:
ALTER TABLE `table` ADD `param_21` BOOL NOT NULL COMMENT 'about the field' AFTER `param_20`
mais il semble une requête très lourde et il prend un temps très long, même sur mon Quad amd PC avec 4 Go de RAM.
Je cours sous windows/xampp et phpMyAdmin. n'mysql avez une entreprise avec chaque enregistrement lors de l'ajout d'un champ? ou puis-je modifier la requête de sorte qu'il rend le changement plus rapidement?
3 réponses
MySQL va, dans presque tous les cas, reconstruire la table lors d'un ALTER**. Cela est dû au fait que les moteurs basés sur les lignes (c'est-à-dire tous les moteurs) doivent le faire pour conserver les données dans le bon format pour les interrogations. C'est aussi parce qu'il y a beaucoup d'autres changements que vous pourriez faire qui nécessiteraient aussi la reconstruction de la table (comme changer les index, les clés primaires, etc.)
Je ne sais pas quel moteur vous utilisez, mais je suppose MyISAM. MyISAM copie le fichier de données, changements de format nécessaires - ceci est relativement rapide et ne devrait pas prendre beaucoup plus de temps que le matériel IO peut obtenir l'ancien fichier de données et le nouveau sur disque.
reconstruire les index est vraiment le tueur. Selon la façon dont vous l'avez configuré, MySQL va soit: pour chaque index, mettre les colonnes indexées dans un tampon filesort (qui peut être en mémoire mais qui est typiquement sur disque), trier que l'aide de sa fonction filesort () (qui fait un quicksort par récursivité copier les données entre deux fichiers, si c'est trop gros pour la mémoire) et ensuite construire l'index entier basé sur les données triées.
S'il ne peut pas faire l'astuce filesort, il se comportera simplement comme si vous avez fait une insertion sur chaque ligne, et peupler les blocs d'index avec les données de chaque ligne à tour de rôle. C'est douloureusement lent et donne des indices loin d'être optimaux.
vous pouvez dire ce qu'il fait en utilisant SHOW PROCESSLIST pendant le processus. "Réparer par filesort" est bien, "réparer avec la clé" c'est mal.
tout cela utilisera au plus un noyau, mais sera parfois lié à IO aussi (en particulier la copie du fichier de données).
** Il y a quelques exceptions, telles que la suppression des index secondaires sur innodb tables du plugin.
vous ajoutez une colonne NOT NULL
, les tuples doivent être remplis. Ainsi, il sera lent...
cela touche chacun des 200.000 enregistrements, car chaque enregistrement doit être mis à jour avec une nouvelle valeur bool qui ne sera pas nulle.
donc; oui c'est une requête coûteuse... Il n'y a rien que vous pouvez faire pour le rendre plus rapide.