Mysql
 sql >> Base de données >  >> RDS >> Mysql

Index InnoDB avant et après l'importation

J'ai un peu expérimenté ce concept lors d'un précédent travail, où nous avions besoin d'une méthode rapide pour copier des schémas entre des serveurs MySQL.

Il y a en effet une surcharge de performances lorsque vous insérez dans des tables qui ont des index secondaires. Les insertions doivent mettre à jour l'index clusterisé (c'est-à-dire la table) et également mettre à jour les index secondaires. Plus une table a d'index, plus elle entraîne de surcharge pour les insertions.

InnoDB a une fonctionnalité appelée change buffer ce qui aide un peu en reportant les mises à jour de l'index, mais ils doivent éventuellement être fusionnés.

Les insertions dans une table sans index secondaire sont plus rapides, il est donc tentant d'essayer de différer la création de l'index jusqu'à ce que vos données soient chargées, comme vous le décrivez.

Percona Server, une branche de MySQL, a expérimenté un mysqldump --optimize-keys option. Lorsque vous utilisez cette option, cela modifie la sortie de mysqldump pour avoir CREATE TABLE sans index, puis INSERT all data, puis ALTER TABLE pour ajouter les index après le chargement des données. Voir https://www.percona.com/doc/ percona-server/LATEST/management/innodb_expanded_fast_index_creation.html

Mais d'après mon expérience, l'amélioration nette des performances était faible. Il faut encore un certain temps pour insérer beaucoup de lignes, même pour les tables sans index. Ensuite, la restauration doit exécuter ALTER TABLE pour créer les index. Cela prend du temps pour une grande table. Lorsque vous comptez le temps des INSERTs plus le temps supplémentaire pour créer des index, ce n'est que quelques pour cent (à un chiffre) plus rapide que l'insertion de la manière traditionnelle, dans une table avec des index.

Un autre avantage de cette création d'index post-traitement est que les index sont stockés de manière plus compacte, donc si vous avez besoin d'économiser de l'espace disque, c'est une meilleure raison d'utiliser cette technique.

J'ai trouvé beaucoup plus avantageux pour les performances de restaurer en chargeant plusieurs tables en parallèle .

  • Le nouvel outil MySQL 8.0 mysqlpump prend en charge le vidage multithread.
  • L'outil open source mydumper prend en charge le vidage multi-thread et dispose également d'un outil de restauration multi-thread, appelé myloader . Le pire inconvénient de mydumper/myloader est que la documentation est pratiquement inexistante, vous devez donc être un utilisateur expérimenté intrépide pour comprendre comment l'exécuter.

Une autre stratégie consiste à utiliser mysqldump --tab pour vider les fichiers CSV au lieu des scripts SQL. Le chargement en bloc de fichiers CSV est beaucoup plus rapide que l'exécution de scripts SQL pour restaurer les données. Eh bien, il vide un fichier SQL pour la définition de la table et un CSV pour les données à importer. Il crée des fichiers séparés pour chaque table. Vous devez recréer manuellement les tables en chargeant tous les fichiers SQL (c'est rapide), puis utiliser mysqlimport pour charger les fichiers de données CSV. L'outil mysqlimport a même un --use-threads option d'exécution parallèle.

Testez soigneusement avec différents nombres de threads parallèles. Mon expérience est que 4 fils est le meilleur. Avec un plus grand parallélisme, InnoDB devient un goulot d'étranglement. Mais votre expérience peut être différente, selon la version de MySQL et la capacité de performance du matériel de votre serveur.

La méthode de restauration la plus rapide de toutes consiste à utiliser un outil de sauvegarde physique, la plus populaire est Percona XtraBackup . Cela permet des sauvegardes rapides et des restaurations encore plus rapides. Les fichiers sauvegardés sont littéralement prêts à être copiés et utilisés comme fichiers d'espace de table en direct. L'inconvénient est que vous devez arrêter votre serveur MySQL pour effectuer la restauration.