J'ai utilisé MySQLTuner qui a souligné que certaines tables étaient fragmentées. j'ai utilisé
mysqlcheck --optimize -A
pour optimiser toutes les tables. Il a corrigé certaines tables mais MySQLTuner trouve toujours 19 tables fragmentées. comment savoir quelles tables ont besoin d'être défragmentées? Peut-être qu'OPTIMIZE TABLE fonctionnera là où mysqlcheck n'a pas fonctionné? Ou quoi d'autre devrais-je essayer?
Réponses:
la réponse courte:
La réponse "Vous devez savoir"
tout d'abord, vous devez comprendre que les tables Mysql sont fragmentées lorsqu'une ligne est mise à jour, c'est donc une situation normale. Lorsqu'une table est créée, disons importée à l'aide d'un vidage avec des données, toutes les lignes sont stockées sans fragmentation dans de nombreuses pages de taille fixe. Lorsque vous mettez à jour une ligne de longueur variable, la page contenant cette ligne est divisée en deux ou plusieurs pages pour stocker les modifications et ces deux nouvelles pages (ou plus) contiennent des espaces vides remplissant l'espace inutilisé.
Cela n'affecte pas les performances, sauf bien sûr si la fragmentation augmente trop. Ce qui est trop de fragmentation, voyons bien la requête que vous recherchez:
DATA_LENGTH et INDEX_LENGTH sont l'espace utilisé par vos données et index, et DATA_FREE est la quantité totale d'octets inutilisés dans toutes les pages de table (fragmentation).
Voici un exemple d'une vraie table de production
Dans ce cas, nous avons une table utilisant (896 + 316) = 1212 Mo, et avons des données sur un espace libre de 5 Mo. Cela signifie un "rapport de fragmentation" de:
... Ce qui est un "taux de fragmentation" vraiment faible.
J'ai travaillé avec des tables avec un ratio proche de 0,2 (soit 20% des espaces vides) et je ne remarque jamais de ralentissement des requêtes, même si j'optimise la table, les performances sont les mêmes. Mais appliquer une table d'optimisation sur une table de 800 Mo prend beaucoup de temps et bloque la table pendant plusieurs minutes, ce qui est impraticable en production.
Donc, si vous considérez ce que vous gagnez en performances et le temps perdu à optimiser une table, je préfère NE PAS OPTIMISER.
Si vous pensez que c'est mieux pour le stockage, voyez votre ratio et voyez combien d'espace pouvez-vous économiser en optimisant. Ce n'est généralement pas trop, donc je préfère NE PAS OPTIMISER.
Et si vous optimisez, la prochaine mise à jour créera des espaces vides en divisant une page en deux ou plus. Mais il est plus rapide de mettre à jour une table fragmentée qu'une table non fragmentée, car si la table est fragmentée, une mise à jour sur une ligne ne divisera pas nécessairement une page.
J'espère que ceci vous aide.
la source
Pour ajouter à la réponse de Felipe-Rojas, vous pouvez calculer le taux de fragmentation dans le cadre de la requête:
Si une table est fragmentée à un faible pourcentage (moins de 5%?), Vous pouvez probablement la laisser seule.
Tout ce qui est plus grand et que vous devrez évaluer en fonction de votre utilisation de la base de données, du verrouillage des tables, etc. quant à l'importance de la défragmentation de la table.
la source
Optimiser la table résoudra en effet le problème que vous rencontrez.
Si vous n'avez que quelques bases de données, vous pouvez utiliser PHPMyAdmin pour parcourir toutes vos bases de données. Sélectionnez les tables avec des frais généraux, puis sélectionnez pour optimiser.
Si vous avez beaucoup de bases de données, une autre méthode serait probablement préférable.
J'utilise la configuration de script PHP suivante dans cron pour exécuter toutes les heures.
la source
mysqlcheck --optimize -A
c'est la même chose que le SQLOPTIMIZE TABLE <tablename>;
Je suis tombé sur cette page et j'ai trouvé les requêtes de Felipe-Rojas et sysadmiral très utiles. Mais dans mon cas, j'exécutais la requête dans phpMyAdmin de WHM et obtenir uniquement TABLE_NAME n'était pas aussi utile car la base de données n'était pas répertoriée et plusieurs bases de données ont les mêmes noms de table. Donc, simplement l'ajout
TABLE_SCHEMA
fournira également cette colonne.Affiche DB
Pour "corriger", j'ai utilisé le lien de la table de défragmentation dans phpMyAdmin pour chacune des tables qui ont abouti à un "frag_ratio" élevé pour lequel phpMyAdmin s'exécute:
la source
Une table utilisant le moteur InnoDB de MySQL n'a pratiquement jamais besoin de l'être
OPTIMIZEd
.La valeur de
Data_free
frominformation_schema.tables
ouSHOW TABLE STATUS
est très souvent non nulle, même si vous pensez avoir fait tout ce que vous pouvez faire pour défragmenter vos tables. De plus, cette métrique n'est qu'une des nombreuses fragmentations qui peuvent se produire et se produisent. (En outre, l'espace perdu dans les blocs, les listes d'annulation, les BTrees d'index vs les BTrees de données, etc., etc.Et
innodb_file_per_table
complique l'utilisation deData_free
. Si la table est dedansibdata1
, seData_free
réfère alors à l'espace de table entier; un nombre plutôt inutile. Si la table se trouve dans son propre.ibd
fichier, il est probable qu'elle représente quelques Mo ou quelques pour cent de la taille de la table, la valeur la plus élevée étant retenue.Ce n'est que si vous avez supprimé de nombreuses lignes et que vous n'avez pas l'intention de recharger la table que cela peut valoir la peine d'être exécuté
OPTIMIZE TABLE
.PARTITIONs
montrent également une quantité inquiétante deData_free
, car chaque partition affiche généralement 4-7 Mo "libre". Et cela ne disparaîtra pas.Pourquoi défragmenter?
innodb_file_per_table=1
. Mais lorsque vous ajoutez des lignes, vous les récupérez du système d'exploitation.Data_free
.Une note d'histoire. Lorsque j'aidais les administrateurs de bases de données avec principalement des tables MyISAM, j'ai découvert peut-être 2 des 1000 tables aidées par un mensuel
OPTIMIZE
. Depuis lors, j'ai travaillé avec des milliers de tables InnoDB, mais je n'ai pas encore trouvé de problème de performance qui pourrait être résoluOPTIMIZE
. (Bien sûr, il y a eu des problèmes d'espace disque pour lesquels celaOPTIMIZE
pourrait aider, mais cela devient délicat - généralement le DBA n'a pas assez d'espace disque pour fonctionnerOPTIMIZE
!)la source