Comment optimiser les tables InnoDB dans MySQL

8

J'ai cherché à optimiser uniquement les tables fragmentées dans MySQL et j'ai examiné ce post sur l'optimisation des tables . Il effectue essentiellement une requête sur la base de données information_schema pour n'importe quelle table data_free > 0et crée une instruction SQL OPTIMIZEuniquement pour ces tables. J'ai exécuté cette requête et il a identifié 148 tables pour l'optimisation. Toutes les tables identifiées sont des tables InnoDB. Après avoir exécuté le script SQL d'optimisation résultant, j'ai réexécuté le script d'origine pour identifier les tables fragmentées et il a renvoyé exactement les mêmes tables lors de la première passe.

J'ai vu des messages contradictoires concernant les tables InnoDB et la OPTIMIZEcommande. Certains disent que OPTIMIZEcela ne fonctionnera pas avec les tables InnoDB et que vous devez l'exécuter ALTER TABLE table_name ENGINE=INNODB. D'autres disent que cela OPTIMIZEappelle la ALTER TABLEcommande lors de l'exécution sur des tables InnoDB. Dans cet esprit, j'ai exécuté la ALTER TABLEcommande contre l'une des tables InnoDB identifiées comme étant fragmentées ( data_free > 0) et j'ai constaté que la data_freen'a pas changé par la suite. Il est toujours supérieur à 0. J'ai également redémarré MySQL et l'ai vérifié uniquement pour trouver les mêmes résultats.

Maintenant, nous avons plusieurs serveurs exécutant MySQL 5.5.29 dans notre organisation et j'ai exécuté une requête sur chacun d'eux pour identifier les tables InnoDB DATA_FREE=0 or NULLet aucune n'a été retournée. Ils sont tous supérieurs à zéro.

J'ai également exécuté la OPTIMIZEcommande sur quelques MyISAMtables où DATA_FREEétait supérieur à zéro et j'ai vérifié que c'était zéro par la suite.

Quelqu'un peut-il faire la lumière sur ce pour moi? Quelle est la bonne méthode pour supprimer la fragmentation des tables InnoDB? Quelle est la bonne méthode pour déterminer les tables InnoDB fragmentées?

Merci

user3151788
la source

Réponses:

9

Je suppose que vous utilisez innodb_file_per_tablecette réponse.

Il existe plusieurs sens à la "fragmentation InnoDB":

  1. .ibd le fichier est fragmenté et est très volumineux alors que l'ensemble de données est petit
  2. Les pages d'index sont fragmentées en ce sens qu'il y a trop de pages pour contenir peu de données, auquel cas elles pourraient être fusionnées.

Veuillez considérer ce post que j'ai écrit il y a un certain temps: il montre comment après avoir purgé de nombreuses lignes d'une grande table, le fichier de données est fragmenté (c'est-à-dire qu'il est très grand dans le système de fichiers - c'est un problème connu que ces fichiers ne réduisent jamais en taille). Et pourtant, les index n'étaient pas fragmentés à la fin de la suppression: c'est parce qu'InnoDB fusionne correctement les pages lorsqu'elles deviennent vides (euh).

La OPTIMIZEcommande ne s'applique en effet pas sur InnoDB. Ce qu'il fait, c'est reconstruire la table (exactement comme un ALTER). Regarde ça:

mysql [localhost] {msandbox} (test) > create table t(id int) engine=innodb;

mysql [localhost] {msandbox} (test) > optimize table t;
+--------+----------+----------+-------------------------------------------------------------------+
| Table  | Op       | Msg_type | Msg_text                                                          |
+--------+----------+----------+-------------------------------------------------------------------+
| test.t | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.t | optimize | status   | OK                                                                |
+--------+----------+----------+-------------------------------------------------------------------+

Quant à DATA_FREE: je suggère que vous ignoriez simplement cette variable. Pour être honnête, je travaille avec les tables InnoDB depuis des 10années et je n'ai jamais trouvé cette valeur très cohérente avec quoi que ce soit.

Et maintenant, il est temps pour la vraie discussion: qu'essayez-vous exactement d'accomplir? À moins que votre base de données ne soit complètement périmée, il y aura toujours une certaine fragmentation. Cela est naturel pour le processus d'ajout, de suppression et de mise à jour des lignes de votre table.

La fragmentation n'est pas si mal: l'espace libre peut être récupéré par de nouvelles données. Si vos tables ne sont pas très grandes, oubliez tout. Pour les très grandes tables, vous pouvez gagner de l'espace disque en optimisant la table. Mais posez-vous la question: combien de temps la table atteindrait-elle la même fragmentation? Une heure? Un jour? Une semaine? À mon humble avis, dans tous ces cas, il est inutile d'optimiser la table.

Néanmoins, si une grande table est massivement purgée de données, ce qui ne devrait pas revenir, je suis pour l'optimisation. Supposons que vous réalisiez que vous disposez de données redondantes qui représentent environ 30% de la taille de votre table. Bien sûr, ce serait formidable de récupérer cet espace disque.

Conclusion: ne considérez ces problèmes qu'avec de très grandes tables; uniquement si vous rencontrez des problèmes d'espace disque.

Shlomi Noach
la source
Je reconnais que data_free n'est pas utile. Il ne compte que l'espace en "extensions libres" pour le tablespace qui est une métrique terrible pour calculer la fragmentation. Je pense que si vous ne l'utilisez pas, innodb_file_per_tableil affichera également la même valeur pour chaque table de l'espace de table partagé.
jeremycole