...

Performance de la version MySQL : impact sur la vitesse et l'évolutivité

Performance de la version MySQL détermine de manière mesurable les temps de réponse, le débit des requêtes et la mise à l'échelle sous charge. Dans cet article, je montre, à l'aide de benchmarks réels, comment MySQL 5.7, 8.0, 8.4, 9.1 et 9.2 s'adapte à la charge de travail. Vitesse et l'évolutivité et quelles sont les étapes de réglage qui en valent la peine.

Points centraux

  • Version choisir : 8.0+ s'échelonne nettement mieux avec une concourance élevée.
  • QPS-Gains : jusqu'à +50% vs. 5.7 lorsque le nombre de threads augmente.
  • 8.4/9.x: optimisations ciblées pour les Writes et les JOINs.
  • Tuning: définir correctement le buffer pool, les threads, les paramètres de tri et de log.
  • Tests: valider ses propres exécutions sysbench sur le matériel cible.

Les bases de la performance MySQL

Je me concentre sur les thèmes clés qui font de MySQL une entreprise rapide : Requêtes, index, mémoire et IO. InnoDB profite fortement d'une bonne gestion de la mémoire tampon, d'une conception propre des schémas et de stratégies d'indexation pertinentes. Les versions modernes réduisent l'overhead du scheduler et améliorent les processus binlog, ce qui réduit les temps d'attente. Je mesure les effets mesurables, surtout pour les plans JOIN, les balayages d'index et le contrôle des threads. Qui veut de la performance donne la priorité Schéma et la configuration avant les mises à niveau du matériel.

MySQL 5.7 vs. 8.0 : mise à l'échelle et QPS

Sous un faible parallélisme, 5.7 fournit des résultats solides, mais lorsque le nombre de threads augmente, la performance s'effondre. Mise à l'échelle La version 8.0 supporte des concentrations plus élevées et augmente souvent le QPS de 30-50% par rapport à la version 5.7 pour les charges de travail OLTP. Les index descendants évitent les filesort et accélèrent sensiblement les lectures. Je vois la plus grande poussée dans les opérations de rang InnoDB et les transactions mixtes lecture/écriture. Un débit plus élevé coûte toutefois un peu plus cher CPU, La plupart du temps, cela reste acceptable sur le matériel actuel.

8.0 Enterprise vs. Community : ce que montrent les benchmarks

Dans les mesures sysbench, 8.0.35 Enterprise atteint souvent 21-34% des valeurs plus élevées. QPS que l'édition communautaire. L'avantage provient de structures internes optimisées et d'une meilleure gestion des threads. Les versions précédentes de la version 8.0 présentaient parfois des régressions lors de DELETE/UPDATE, que les correctifs ultérieurs ont éliminées. Je tiens donc compte des niveaux de patch et je teste de manière ciblée les requêtes critiques. Celui qui planifie la mise à l'échelle calcule la plus-value par rapport aux coûts plus élevés. CPU-Les décisions relatives à la charge et à l'édition sont prises en fonction des besoins.

Aperçu des progrès réalisés dans les versions 8.4 et 9.x

Avec les versions 8.4.3 et 9.1.0, les modifications apportées au suivi des dépendances binlog augmentent considérablement les charges de travail d'écriture, environ +19,4% lors des mises à jour. Les optimisations JOIN (+2,17%) et les meilleurs scans d'index (+2,12%) ajoutent des gains incrémentaux. Sur de nombreuses charges de travail, je vois environ +7,25% en écritures et +1,39% en lectures. 9.1.0 n'est que très légèrement (≈0,68%) derrière 8.4.3, mais se rapproche de 8.0.40. Dans les scénarios de type TPC-C, la version 9.2 est souvent considérée comme la meilleure. évolutif et constante, surtout au-delà de 128 threads.

Version Avantage principal Gain typique Remarque
5.7 Faible Concurrence - Facile à utiliser, s'adapte moins bien à une charge élevée.
8.0 Descending Indexes, de meilleurs fils +30-50% QPS vs. 5.7 Utilisation accrue de l'unité centrale, avantages évidents pour l'OLTP.
8.4.3 Dépendance Binlog optimisée Writes +7,25% Gains supplémentaires en cas de JOIN et de balayage de la gamme.
9.1.0 Peaufinage sur Optimiseur et journalisation ≈-0,68% vs. 8.4.3 Proche de 8.4.3 ; résultats cohérents.
9.2 Nombre élevé de fils de discussion Top à >128 fils Très bonne Mise à l'échelle en mode de charge élevée.

J'utilise ce tableau comme aide à la décision : d'abord la charge de travail, puis la version, ensuite le réglage fin. Les personnes travaillant en mode Write ressentent davantage les effets des versions 8.4/9.x. Les applications à dominante lecture profitent déjà sensiblement de 8.0. Pour une croissance constante, la version 9.2 reste une valeur sûre. Il est important d'avoir une stratégie de mesure par matériel cible.

Lire et utiliser correctement les benchmarks OLTP

Je n'évalue pas les benchmarks de manière isolée, mais dans le contexte de mes propres objectifs de latence et de débit. Read-Only, Point-Selects et Read-Write se comportent différemment et exigent des analyses différenciées. interprétation. Les pics QPS ne sont convaincants que si les 95e/99e percentiles restent stables. Les charges de production mélangent souvent des SELECT courts avec des phases UPDATE/INSERT intensives. Pour les premières étapes d'optimisation, je vous renvoie à la page compacte Conseils de tuning, avant d'aller plus loin.

Tuning : configuration avec effet

Je mets le Pool de mémoire tampon généralement à environ 70% de la RAM disponible, afin que les données chaudes restent en mémoire. parallel_query_threads, je l'utilise de manière contrôlée, car trop de parallélisme attire, mais limite les dépendances. sort_buffer_size, je l'augmente en fonction des besoins et évite les excès globaux. Les paramètres binlog et les stratégies de flush influencent la latence et le temps de réponse. Débit est perceptible. Je mesure chaque changement avant de continuer à tourner, ce qui me permet de garantir des résultats reproductibles. Effets.

Des leviers de config souvent négligés

  • Redo/Undo : innodb_log_file_size et innodb_redo_log_capacity de manière à ce que les points de contrôle ne soient pas pressés trop souvent sans faire exploser le temps de récupération. Pour les phases d'écriture, je compte avec >4-8 Go de redo comme point de départ et je valide avec des mesures de niveau de redo.
  • Flush/IO : innodb_flush_neighbors sur les SSD/NVMe modernes, innodb_io_capacité(_max) adapter à de véritables IOPS, afin que le flush LRU n'arrive pas par vagues.
  • Change Buffer : pour de nombreuses écritures d'index secondaires, le Tampon de changement aider ; vérifier avec le monitoring s'il soulage effectivement ou s'il déplace la pression.
  • Tables Tmp : tmp_table_size et max_heap_table_size dimensionner de manière à ce que les petits types fréquents restent dans la RAM ; optimiser de manière ciblée les grands types rares plutôt que de les gonfler globalement.
  • Rejoindre/trier join_buffer_size et sort_buffer_size car ils sont alloués par fil de discussion. J'optimise les indices/plans en premier, les buffers en dernier.
  • Durabilité : sync_binlog, innodb_flush_log_at_trx_commit et binlog_group_commit choisir consciemment : 1/1 est une sécurité maximale, des valeurs plus élevées réduisent la latence avec un risque calculable.

Moteurs de stockage et modèles de charge de travail

La norme est InnoDB, mais les charges de travail sont très différentes. J'examine si les index secondaires, les contraintes FK et les caractéristiques ACID sont compatibles avec le système réel. Cas d'utilisation soutenir les données. En archivant les anciennes données, on allège les tables primaires et on réduit les ensembles de travail. Pour les connaissances de base sur les moteurs, une vue d'ensemble compacte telle que InnoDB vs MyISAM. Au final, ce qui compte, c'est que le moteur, les index et les requêtes forment ensemble un ensemble cohérent. Profil se produisent.

Planifier des chemins de mise à niveau sans risque

Je fais une mise à niveau progressive : 5.7 → 8.0 → 8.4/9.x, accompagnée de contrôles de régression. Avant le changement, je gèle les modifications de schémas et je crée des Tests. Ensuite, je compare les plans de requête, les centiles et les verrous. Les stratégies Blue Green ou Read-Replica-Failover réduisent les temps d'arrêt. Celui qui planifie proprement profite rapidement des nouveaux Caractéristiques et une plus grande efficacité.

Suivi et méthodologie de test

Je mesure avec Sysbench, j'ajoute des métriques issues de Performance Schema et d'outils comme Percona Toolkit. Les 95e/99e percentiles et la moyenne sont plus décisifs qu'une moyenne élevée. variance. Les analyses Query-Digest révèlent les modèles coûteux avant qu'ils ne deviennent coûteux. Les reproductions de charges de production réelles fournissent de meilleures informations que les tests synthétiques seuls. Sans une analyse continue Suivi les mises à niveau restent aveugles.

MariaDB vs. MySQL : le choix pragmatique

MariaDB 11.4 marque des points dans certains scénarios INSERT avec un avantage de 13-36% par rapport à MySQL 8.0. MySQL 8.0 brille en OLTP et avec un nombre élevé de threads, tandis que 9.2 est le plus puissant pour >128 threads. Mise à l'échelle montre. Je décide en fonction de la charge de travail : Write-heavy avec de nombreuses petites transactions, ou charge OLTP mixte avec de nombreuses lectures. Les deux systèmes fournissent des résultats fiables si la configuration et le schéma sont propres. Le choix reste une question de Charge de travail, le savoir-faire de l'équipe et la feuille de route.

Stabilité des plans, statistiques et astuces d'indexation

Une mise à niveau permet rarement d'augmenter le débit, mais aussi d'utiliser de nouvelles heuristiques d'optimisation. J'assure la stabilité du plan en contrôlant délibérément les analyses et les statistiques. Statistiques persistantes et régulière ANALYSE TABLE Les runs gardent les cardinalités réalistes. Lorsque les distributions de données sont fortement skewed, les Histogrammes (dans 8.0+) souvent plus que des extensions d'index globales. Pour les requêtes sensibles, j'utilise de manière ciblée Conseils d'optimisation, Les utilisateurs peuvent utiliser la fonction d'optimisation, mais avec parcimonie, afin que les versions futures puissent continuer à optimiser librement.

Index invisibles je l'utilise pour tester sans risque l'effet des suppressions d'index. Index fonctionnels et Colonnes générées accélèrent les filtres fréquents sur les expressions ou les champs JSON et évitent les coûteux filesort/tmp-changement de chemin. Je garde les clés primaires monotones (AUTO_INCREMENT ou variantes d'UUID basées sur le temps) afin que les splits de pages et les écritures d'index secondaires ne s'étendent pas. Ceux qui viennent d'UUID aléatoires mesurent l'effet d'un changement sur l'insert locality et Flush-charge.

Réplication et basculement avec focalisation sur la performance

Pour un taux d'écriture élevé, je choisis ROW-avec un regroupement judicieux (group commit) et mesure le trade-off entre sync_binlog=1 et 0/100. Sur les répliques, échelle slave_parallel_workers (ou. replica_parallel_workers) avec 8.0+ nettement mieux, si Suivi des dépendances fonctionne proprement. Dans les scénarios de basculement, la semi-synchronisation accélère le RTO, mais peut augmenter la latence - je l'active de manière sélective sur les chemins critiques.

Je fais attention aux détails : binlog_checksum et la compression coûtent du CPU, mais économisent de l'IO ; binlog_expire_logs_seconds empêche la croissance des logs. Sur les répliques, je garde read_only strictement afin d'éviter les divergences, et teste Réplication différée comme protection contre les mises à jour de masse erronées. Pour les pics de charge, il est utile d'assouplir temporairement les paramètres Binlog Flush, tant que les SLO et les RTO le permettent.

Gestion des connexions et des threads

De nombreux goulets d'étranglement n'apparaissent pas dans le stockage, mais dans le Gestion des connexions. Je pense que max_connections réaliste (pas maximal), augmente thread_cache_size et je mise avant tout sur Pools de connexion de l'application. Je fais évoluer les connexions courtes et fréquentes par le biais de la mise en commun, et non par le nombre de connexions nues. wait_timeout et interactive_timeout je limite pour éviter les cadavres, et j'observe Threads_running vs. Threads_connectés.

En cas de parallélisme élevé, j'effectue une réduction de débit ciblée : innodb_thread_concurrence je laisse généralement 0 (auto), mais j'interviens lorsque les charges de travail commutent de manière excessive dans le contexte. table_open_cache et table_definition_cache je le dimensionne de manière à ce que les schémas à chaud ne soient pas constamment rouverts. Dans la version 8.0+, l'ordonnanceur bénéficie de meilleurs mutex, mais j'empêche quand même troupeaux tonitruants, J'ai également pu améliorer la qualité de l'application en intégrant le backoff de l'application et l'exponential retry au lieu de faire des boucles difficiles.

Matériel, OS et réalité des conteneurs

MySQL n'exploite le matériel moderne que si les fondations sont bonnes. Sur les machines NUMA, j'épingle la RAM (entrelacée) ou je lie le processus à quelques nœuds afin d'éviter les latences inter-nœuds. Pages transparentes volumineuses je désactive le swapping ; le scheduler IO est sur none (NVMe) ou. mq-deadline. Je fixe le scaling du CPU sur le gouverneur de performance, afin que les pics de latence ne proviennent pas des changements de fréquence.

Au niveau du système de fichiers, je veille à ce que les options d'alignement et de montage soient propres et je sépare le binlog, le redo et les données lorsque plusieurs NVMe sont disponibles. Dans les conteneurs, je définis les ressources en dur (ensembles de CPU, limites de mémoire) et je teste le comportement Fsync de la couche de stockage. Le throttling de Cgroup explique sinon les prétendus „bugs de DB“. Celui qui virtualise vérifie le contrôle des interruptions, le cache d'écriture et le contrôleur sur batterie - et vérifie que O_DIRECT est vraiment transférée.

Modèle de données, jeux de caractères et efficacité du stockage

Lors de la mise à niveau vers la version 8.0+, le utf8mb4 Standard - bon pour la compatibilité, mais les index et la taille des rangées augmentent. Je vérifie plus généreusement les longueurs VARCHAR et j'utilise délibérément des collations pour contrôler les coûts de tri. Je garde les types de données petits (par ex. INT au lieu de BIGINT, ) et utilise les GENERATED des colonnes pour rendre les filtres calculés indexables. Pour les très grandes tables, la compression vaut la peine si le budget CPU est disponible ; sinon, je gagne plus par la réduction des hot-sets (archivage, partitionnement) que par les degrés de compression bruts.

Les clés primaires sont une politique de performance : faciliter les clés monotones Insert Locality et réduisent les Page Splits ; les clés aléatoires augmentent la latence et l'amplification en écriture. Je nettoie régulièrement les index secondaires - „nice to have“ coûte linéairement en charges d'écriture. J'évalue l'utilité et la fréquence des requêtes avant de conserver les index.

Tester en toute sécurité, dérouler en toute sécurité

Je structure les releases en phases : Shadow-Traffic contre une instance identique 8.0/8.4/9.x, puis décalage progressif du trafic (Canary, 5-10-25-50-100%). Je compare les plans de requête par analyse digest ; en cas de divergence, je détermine si des histogrammes, des indices ou des index ferment le chemin de régression. Point important : 8.0 apporte un nouveau Dictionnaire de données; Les retours à la version 5.7 sont pratiquement impossibles - les sauvegardes sont donc obligatoires avant tout cut-over définitif.

Je simule des basculements, je reproduis des temps de reprise et des comportements de réplication réels et je vérifie la rétention des logs pour d'éventuels rewinds. Retour en arrière je planifie de manière pragmatique : config-toggle, feature flags, retour rapide aux builds précédentes, pas seulement aux versions de la DB. Et je documente chaque étape de réglage avec des métriques - sans points de mesure, il n'y a pas d'effet d'apprentissage pour la prochaine itération.

Résumé et guide de décision

Je retiens que la version 8.0 offre de grandes avancées en matière de QPS par rapport à la version 5.7, et que les versions 8.4 et 9.x font progresser les écritures et les JOINs. Ceux qui planifient au-delà de 128 threads profitent fortement de la version 9.2 et de l'amélioration conséquente de la qualité. Tuning. J'obtiens les gains les plus rapides avec la taille du buffer pool, des index appropriés et des paramètres binlog propres. Ensuite, ce qui compte, c'est la conception des requêtes, l'analyse de la latence et un chemin de mise à niveau sans surprises. Avec cette feuille de route, on peut Performance augmenter de manière mesurable et exploiter de manière fiable.

Derniers articles