J'ai une table InnoDB que je souhaite modifier. Le tableau compte environ 80 millions de lignes et quitte quelques indices.
Je veux changer le nom d'une des colonnes et ajouter quelques indices supplémentaires.
- Quel est le moyen le plus rapide de le faire (en supposant que je pourrais subir même des temps d'arrêt - le serveur est un esclave inutilisé)?
- La
alter table
solution "simple" est -elle la plus rapide?
En ce moment, tout ce qui m'importe c'est la vitesse :)
SHOW CREATE TABLE tblname\G
indiquer la colonne à modifier, le type de données de la colonne et le nouveau nom de la colonne.sent_at
et pour lui ajouter quelques indices supplémentairesRéponses:
Un moyen sûr d'accélérer une ALTER TABLE est de supprimer les index inutiles
Voici les étapes initiales pour charger une nouvelle version du tableau
Veuillez noter ce qui suit:
J'ai laissé tomber source_persona_index car c'est la première colonne de 4 autres index
J'ai supprimé target_persona_index car c'est la première colonne de 2 autres index
J'ai supprimé target_persona_relation_type_index car les 2 premières colonnes se trouvent également dans target_persona_relation_type_message_id_index
OK Cela prend en charge les index inutiles. Y a-t-il des index à faible cardinalité? Voici la façon de déterminer que:
Exécutez les requêtes suivantes:
Selon votre question, il y a environ 80 000 000 lignes. En règle générale, MySQL Query Optimizer n'utilisera pas d'index si la cardinalité des colonnes sélectionnées est supérieure à 5% du nombre de lignes de table. Dans ce cas, ce serait 4 000 000.
COUNT(DISTINCT sent_at)
> 4 000 000ALTER TABLE s_relations_new DROP INDEX sent_at_index;
COUNT(DISTINCT message_id)
> 4 000 000ALTER TABLE s_relations_new DROP INDEX message_id_index;
COUNT(DISTINCT target_object_id)
> 4 000 000ALTER TABLE s_relations_new DROP INDEX target_object_index;
Une fois l'utilité ou l'inutilité de ces index déterminées, vous pouvez recharger les données
C'est ça, non? NAN !!!
Si votre site Web a été mis en place pendant tout ce temps, des INSERT peuvent s'exécuter sur s_relations lors du chargement de s_relations_new. Comment pouvez-vous récupérer ces lignes manquantes?
Allez trouver l'ID maximum dans s_relations_new et ajoutez tout après cet ID dans s_relations. Pour vous assurer que la table est figée et utilisée uniquement pour cette mise à jour, vous devez disposer d'un petit temps d'arrêt afin d'obtenir les dernières lignes insérées dans s_relation_new. Voici ce que vous faites:
Dans l'OS, redémarrez mysql pour que personne d'autre ne puisse se connecter mais root @ localhost (désactive TCP / IP):
Ensuite, connectez-vous à mysql et chargez ces dernières lignes:
Ensuite, redémarrez mysql normalement
Maintenant, si vous ne pouvez pas supprimer mysql, vous devrez faire un appât et basculer sur s_relations. Connectez-vous simplement à mysql et procédez comme suit:
Essaie !!!
CAVEAT: Une fois que vous êtes satisfait de cette opération, vous pouvez déposer l'ancienne table à votre convenance:
la source
La bonne réponse dépend de la version du moteur MySQL que vous utilisez.
Si vous utilisez 5.6+, les renommages et l'ajout / suppression d'index sont effectués en ligne , c'est-à-dire sans copier toutes les données de la table.
Utilisez-le
ALTER TABLE
comme d'habitude, il sera principalement instantané pour les renommages et les suppressions d'index, et assez rapide pour l'ajout d'index (aussi rapide que la lecture de toute la table une fois).Si vous utilisez 5.1+ et que le plugin InnoDB est activé, l'ajout / la suppression d'index sera également en ligne. Pas sûr de renommer.
Si vous utilisez une ancienne version,
ALTER TABLE
c'est toujours la plus rapide, mais elle sera probablement horriblement lente car toutes vos données seront réinsérées dans une table temporaire sous le capot.Enfin, il est temps de démystifier le mythe. Malheureusement, je n'ai pas assez de karma ici pour commenter les réponses, mais je pense qu'il est important de corriger la réponse la plus votée. C'est faux :
C'est en fait l' inverse .
Les indices sont utiles pour sélectionner quelques lignes, il est donc important qu'ils aient une cardinalité élevée , ce qui signifie de nombreuses valeurs distinctes et statistiquement peu de lignes avec la même valeur.
la source
RENAME TABLE
instantané (comme prévu) mais unCHANGE COLUMN
pour renommer la clé primaire a fait une copie complète ... 7 heures! Peut-être uniquement parce que c'était la clé primaire? Pas bon.J'ai eu le même problème avec Maria DB 10.1.12, puis après avoir lu la documentation j'ai trouvé qu'il y avait une option pour effectuer l'opération "sur place" ce qui élimine la copie du tableau. Avec cette option, la table alter est très rapide. Dans mon cas, c'était:
c'est très rapide. Sans l'option d'algorithme, il ne se terminerait jamais.
https://mariadb.com/kb/en/mariadb/alter-table/
la source
Pour la colonne renommer,
devrait être bien et ne porter aucun temps d'arrêt.
Pour les index, l'instruction CREATE INDEX verrouille la table. Si c'est un esclave inutilisé comme vous l'avez mentionné, ce n'est pas un problème.
Une autre option serait de créer une toute nouvelle table contenant les noms de colonne et les index appropriés. Ensuite, vous pouvez y copier toutes les données, puis exécuter une série de
Cela minimiserait les temps d'arrêt au prix d'une utilisation temporaire de deux fois l'espace.
la source
J'ai aussi ce problème et j'ai utilisé ce SQL:
J'espère que ça pourrait aider quelqu'un
Cordialement,
Volonté
la source