11
votes

MySQL Alter Table sur une très grande table - est-il sans danger de l'exécuter?

J'ai une base de données MySQL avec une table myisam avec 4 millions de lignes. Je mettez à jour ce tableau environ une fois par semaine avec environ 2000 nouvelles lignes. Après la mise à jour, je modifie ensuite la table comme celle-ci:

ALTER TABLE x ORDER BY PK DESC


1 commentaires

Je pense que "très grande table" est probablement une surestimation. 4m rangs n'est pas une très grande table. 1bn pourrait éventuellement être.


5 Réponses :


0
votes

Je créerais probablement une vue à la place qui est commandée par la valeur PK, de sorte que, pour une chose, vous n'avez pas besoin de verrouiller cette énorme table pendant l'exécution de l'altération.


2 commentaires

Merci pour la réponse ... La chose est que cela ne me dérange pas de verrouiller la table pendant la mise à jour car elle sera hors ligne de toute façon ...


Je ne crois pas qu'une vue aidera ici. MySQL a [deux stratégies] [1] pour afficher les résolutions: Fusionner et tentable . Lorsque vous utilisez la fusion, vous ne gagneriez aucun avantage car sa définition est simplement fusionné avec l'instruction SELED SELECT . tentable , comme le nom le suggère, créera une table temporaire. Mais la façon dont il a l'air, la création de la table temporaire est la cause du problème initial. Donc, vous ne gagneriez rien sauf faire de la maintenance plus difficile. [1]: dev.mysql.com/doc/refman/ 5.0 / FR / VIEW-ALGORITHMES.HTML



3
votes

Comme je viens de lire, le alter Table ... commander par ... La requête est utile pour améliorer les performances dans certains scénarios. Je suis surpris que l'indice PK ne aide pas à cela. Mais, de The MySQL Docs , il semble que InnoDB fait l'indice. Cependant InnoDB a tendance à être plus lente que Myisam. Cela dit, avec InnoDB, vous n'avez pas besoin de remédier à la table, mais vous perdriez la vitesse flamboyante de Myisam. Cela vaut toujours un coup.

La façon dont vous expliquez les problèmes, il semble qu'il y a trop de données chargées dans la mémoire (peut-être qu'il y a même échanger?). Vous pouvez facilement vérifier cela avec la surveillance de votre utilisation de la mémoire. Il est difficile de dire que je ne connais pas MySQL tout ça bien.

D'autre part, je pense que votre problème réside dans un endroit très différent: vous utilisez une machine avec seulement 512 MEGS de RAM en tant que serveur de base de données avec une table contenant plus de 4 lignes ... et vous effectuez un très Fonctionnement Heavy-Heavy sur toute la table sur cette machine. Il semble que 512 membres ne suffisent pas presque pour cela.

Un problème beaucoup plus fondamental que je vois ici: vous faites du développement (et des tests très probables également) dans un environnement très différent de l'environnement de production. Le genre de problème que vous expliquez est à prévoir. Votre machine de développement a six fois plus de mémoire que votre machine de production. Je crois que je peux dire en toute sécurité que le processeur est beaucoup plus rapide aussi bien. Dans ce cas, je vous suggère de créer une machine virtuelle imitant votre site de production. De cette façon, vous pouvez facilement tester votre projet sans perturber le site de production.


2 commentaires

Des améliorations récentes à InnoDB ont permis de se produire au pair avec Myisam dans la plupart des scénarios.


@Bill: intéressant. Donc, avec cela, vous pourriez dire que InnoDB est vraiment la voie à suivre? Même performance, plus de fonctionnalités. Après avoir vu votre profil, je pense que je peux vous croire. Pourtant, avez-vous une preuve d'aller avec ça?



1
votes

Qu'est-ce que vous demandez à faire est de reconstruire la table entière et tous ses index; Ceci est une opération coûteuse, en particulier si les données ne correspondent pas à la RAM. Il terminera, mais il sera considérablement plus lent si les données ne correspondent pas à la RAM, en particulier si vous avez beaucoup d'index.

Je me demande votre jugement lorsque vous choisissez d'exécuter une machine avec une telle mémoire en production. Quoi qu'il en soit:

  • Est-ce que cette table alter est vraiment nécessaire; Quelle requête spécifique essayez-vous d'accélérer et d'avoir essayé-le sans?
  • Avez-vous envisagé de rendre votre machine de développement plus comme une production? Je veux dire, en utilisant une boîte DEV avec plus de mémoire n'est jamais une bonne idée, et l'utilisation d'un système d'exploitation différent n'est certainement pas non plus.

    Il y a probablement aussi un réglage que vous pouvez faire pour essayer d'aider; Cela dépend en grande partie de votre schéma (index en particulier). 4M rangées n'est pas très nombreuses (pour une machine avec des quantités normales de RAM).


5 commentaires

Salut mark ... Merci pour votre réponse ... La limite de la mémoire est due à des considérations budgétaires ... Je pensais que si le site surpris, je mettrai la mise à jour des spécifications du serveur ... Cependant, la raison de faire le Alter est que les utilisateurs peuvent exécuter une procédure stockée qui intervient ce tableau et je souhaite renvoyer les résultats par ordre de "Dernier inséré en premier". Je peux y parvenir en utilisant une commande par la requête elle-même, mais malheureusement, cela semble être très coûteux et ralentit les requêtes considérablement ... Donc, lorsque je tiens à mettre à jour la table, je pré-commande habituellement par Pk Desc pour ignorer cette commande.


Vous devez créer un index approprié pour que la commande par requête n'a pas besoin de trier. Vous pouvez vérifier cela en utilisant Expliquer (seulement si la requête n'est pas dans un SP). Alter Tableau ... La commande par n'est pas une solution, car elle ne garantit pas les données qui restent commandées.


Salut Mark. J'ai 8 index sur cette table. Si je devais ajouter le champ PK (que je souhaite commander par Desc) à la partie la plus à droite de chacun de ces index, les index seront toujours utilisés pour satisfaire la clause WHERE et, même si le champ de commande ne sera pas le plus à gauche Préfixe de l'indice (comme je l'ajouterai à la droite de chaque indice), il peut toujours être utilisé pour la commande par? Merci.


Malheureusement, j'ai ajouté la commande par champ à un index, mais explique toujours qu'il utilise des fichiers. Je ne pense pas que je puisse inclure la commande par champ dans un indice de sorte que la clause de l'endroit où la clause utilise également un indice. .J'ai également essayé "Select * à partir de (Sélectionnez la requête principale) Commander par ..." Mais cela prend toujours beaucoup plus de temps que sans la commande par clause ...


Vous auriez besoin d'un index avec les deux colonnes dans le bon ordre. Publiez une autre question contenant votre schéma, votre requête et votre plan explique.



0
votes

Si vous utilisez InnoDB, vous ne devriez pas avoir à effectuer explicitement la commande par soit post-insertion, soit au moment de la requête. Selon le manuel MySQL 5.0, InnoDB est déjà par défaut à la commande principale des résultats de la requête:

http://dev.mysql.com /doc/refman/5.0/fr/alter-Table.html#id4052480

Tables Myisam Retourner les enregistrements de retour dans l'ordre d'insertion par défaut, ce qui peut également fonctionner si vous ne pouvez également ajouter à la table, plutôt que d'utiliser une requête update pour modifier les lignes en place.


0 commentaires

1
votes

est la principale clé auto_incrètie? Si tel est le cas, alors faire une table d'alimentation ... L'ordre ne va pas améliorer quoi que tout soit inséré dans l'ordre.

(sauf si vous avez beaucoup de suppression)


2 commentaires

Merci pour la réponse. Cependant, le problème est que je souhaite donner les résultats dans l'ordre inverse de l'ordre clé principal ...


Ensuite, vous devez optimiser vos procédures, vos requêtes et vos paramètres de serveur stockés, sans essayer des objets black-magiques tels que Alter Table, qui ne fonctionne que grâce à une bizarrerie dans les tables de Myisam. Si la performance de vos procédures et de vos requêtes stockées souffrez lorsque vous les triez, vous devez ouvrir une nouvelle question et publier l'instruction Créer une table, la requête / la procédure et la sortie Explique. Ensuite, nous pouvons vous aider à optimiser la requête ou à votre configuration du serveur.