Comment améliorer les performances de MySQL INSERT et UPDATE?

14

Cette question peut probablement aussi être posée sur StackOverflow, mais je vais essayer ici d'abord ...

Les performances des instructions INSERT et UPDATE dans notre base de données semblent se dégrader et entraîner de mauvaises performances dans notre application Web.

Les tables sont InnoDB et l'application utilise des transactions. Y a-t-il des ajustements faciles à faire pour accélérer les choses?

Je pense que nous pouvons voir des problèmes de verrouillage, comment puis-je le savoir?

mmattax
la source
Mieux sur dba.stackexchange.com
Pacerier

Réponses:

25
  1. Vérifiez si votre matériel et votre système d'exploitation sont correctement configurés et réglés:

    • Source du problème (utilisation CPU / IO / mémoire / swap). Avez-vous beaucoup d'IOP? Le processeur est-il chargé? Si vous avez beaucoup de IOP de lecture, vous n'avez probablement pas assez de gros pool de tampons InnoDB. Si le processeur est chargé, vos requêtes effectuent des analyses de table complètes au lieu d'utiliser des index appropriés.
    • Configuration disque / RAID / LVM. Dans certaines configurations spécifiques, l' entrelacement LVM pourrait vous apporter des avantages en égalisant la charge du disque (pas de RAID matériel, plusieurs LUN connectés)
    • Planificateur IO: lorsque vous avez un bon contrôleur RAID matériel, noop est probablement le meilleur. RedHat a fait quelques tests et ils ont dit que pour Oracle (et autres DB) CFQ est le meilleur choix. Vous devez exécuter des benchmarks (comme tpc-c ou tpc-e) et choisir ce qui convient le mieux à votre matériel.
    • Bon système de fichiers - ext3 ne fonctionne pas bien dans les charges de travail spécifiques à la base de données. Mieux vaut XFS ou OCFS2. Vous avez encore besoin de repères.
    • Regardez, si votre système utilise le swap. L'utilisation de swap dégrade les performances de mysql .
  2. Vérifiez si votre instance MySQL / InnoDB est correctement réglée:

    • taille du pool de tampons - mettre en cache les pages de données en mémoire
    • innodb_flush_method = O_DIRECT - évite le double tampon IO
    • augmenter la taille du fichier journal InnoDB - pour une charge de travail intensive en écriture, cela pourrait améliorer les performances. Mais n'oubliez pas: une taille de fichier journal plus grande signifie une récupération après incident plus longue. Parfois en quelques heures !!!
    • innodb_flush_log_at_trx_commit = 0 ou 2 - Si vous n'êtes pas préoccupé par ACID et pouvez perdre des transactions pour la dernière seconde ou deux.
    • key_buffer_size - très important pour MyISAM, mais il est utilisé pour les tables temporaires de disque.
    • Surveillez votre STATUT INNODB
  3. Analysez votre charge de travail - récupérez toutes vos requêtes dans le journal des requêtes lentes et exécutez mk-query-digest dessus. Vous pouvez intercepter toutes les requêtes en utilisant tcpdump et maatkit
    • Quelles requêtes prennent le plus de temps sur votre serveur?
    • Des tables temporaires sont-elles créées, en particulier les grandes tables temporaires?
    • Apprenez, comment utiliser expliquer
    • Votre application utilise-t-elle des transactions? Lorsque vous exécutez des requêtes avec autocommit = 1 (par défaut sur MySQL), chaque requête d'insertion / mise à jour commence une nouvelle transaction, ce qui entraîne une surcharge. Si cela est possible, mieux vaut désactiver l'autocommit (dans le pilote python MySQL, l'autocommit est désactivé par défaut) et exécuter manuellement la validation une fois toutes les modifications effectuées.
    • Votre application effectue-t-elle une série d'insertions dans la même table en boucle? Load data infilela commande est beaucoup plus rapide pour les séries d'inserts.
    • Rappelez-vous: select count(*) from table;est beaucoup plus lent pour innodb que pour myisam.
    • Quels types de requêtes INSERT / UPDATE prennent le plus de temps sur le serveur? Comment peuvent-ils être optimisés?
    • Vérifiez si votre base de données possède des index appropriés et ajoutez-les si nécessaire.

Dans notre environnement, nous avions une situation, ce type de requêtes de mise à jour était lent. Le temps estimé pour terminer le travail par lots était de 2 jours !!! Après avoir analysé le journal des requêtes lentes, nous constatons que ce type de requête de mise à jour a besoin de 4 secondes pour se terminer. Requête ressemblait à ceci: update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. Après avoir converti la requête de mise à jour en requête de sélection et exécuté expliquer sur cette requête de sélection que nous trouvons, ce type de requête n'utilise pas d'index. Après avoir créé un index approprié, nous avons réduit le temps d'exécution des requêtes de mise à jour à des millisecondes et le travail complet s'est terminé en moins de deux heures.

Quelques liens utiles:

sumar
la source
Avant tout ça, vérifiez les indices. Dégrader les SMELL comme "à mesure que les tables grossissent parce que nous n'avons pas d'indices".
TomTom
5

Avec la configuration par défaut innoDB, vous serez limité à la vitesse à laquelle vous pouvez écrire et vider les transactions sur le disque. Si vous pouvez gérer la perte d'un petit ACID, essayez avec innodb_flush_log_at_trx_commit. Définissez sur 0 pour écrire et vider le journal sur le disque toutes les secondes. Défini sur 1 (par défaut) pour écrire et vider à chaque validation. Définissez-le sur 2 pour écrire dans le fichier journal après chaque validation, mais ne vider qu'une seule fois par seconde.

Si vous pouvez gérer la perte de 1 de transactions, cela peut être un excellent moyen d'améliorer considérablement les performances d'écriture.

Faites également attention à ce que font vos disques. RAID 10> RAID 5 pour les écritures au prix d'un disque supplémentaire.

tomchuk
la source
1

Les problèmes de verrouillage seront examinés par les états de connexion dans show full processlist;

Lisez la my.cnfdocumentation MySQL et. Les options de configuration sont très bien documentées.

D'une manière générale, vous souhaitez que le plus possible de traitement en mémoire. Pour l'optimisation des requêtes, cela signifie éviter les tables temporaires. Application correcte des index.

Le réglage va être spécifique à votre moteur de base de données préféré et à votre architecture d'application. Il existe des ressources substantielles préexistant à une recherche sur Internet.

Warner
la source
0

InnoDB est un assez bon moteur. Cependant, il dépend fortement d'être «réglé». Une chose est que si vos insertions ne sont pas dans l'ordre d'augmentation des clés primaires, innoDB peut prendre un peu plus de temps que MyISAM. Cela peut facilement être surmonté en définissant une taille innodb_buffer_pool_size plus élevée. Ma suggestion est de le définir à 60-70% de votre RAM totale. J'exécute 4 de ces serveurs en production maintenant, en insérant environ 3,5 millions de lignes par minute. Ils ont déjà près de 3 téraoctets. InnoDB cela devait être, à cause des insertions hautement simultanées. Il existe d'autres moyens d'accélérer les insertions. Et j'en ai comparé certains.

Ajay Divakaran
la source
0

Comment résoudre les problèmes d'insertion et de mise à jour des performances dans MySQL dans l'application Web simplement en désactivant les modifications de validation automatique et de validation une fois en Java. Comme suggéré dans la documentation mysql.

Documents MySQL

Jatinder
la source