D'énormes différences de performances de MySQL sur deux serveurs

8

Nous avons un serveur MySQL installé sur deux machines différentes, un serveur de test et un serveur de production, les deux fenêtres, qui est utilisé par une application Web.

Le problème est qu'il existe d'énormes différences de performances entre les deux machines lors de l'exécution de certaines requêtes (le serveur de production étant le plus lent). La version MySQL sur les deux serveurs est la même, même les fichiers de configuration sont les mêmes (la seule différence est le chemin des données et le fait que le serveur de production n'enregistre rien sauf les erreurs). La différence de performances dont je parle est supérieure de 3 ou 4 ordres de grandeur (par exemple, une requête dans le serveur de test s'exécute en 0,2 s, tandis que dans le serveur de production s'exécute en 84 s).

Les requêtes incriminées font un usage intensif des clauses avec "WHERE [...] IN [...]", ce qui, à mon avis, sont généralement très lentes et doivent être remplacées par JOIN. Cependant, la version de MySQL que nous utilisons est 5.6.19, qui optimise automatiquement ces requêtes, c'est pourquoi elles fonctionnent rapidement dans le serveur de test (et elles font partie d'une partie du programme que nous ne pouvons pas changer, donc nous ne pouvons pas les optimiser manuellement). en tous cas).

Comme je l'ai dit, l'installation et la configuration de MySQL sont identiques, donc je ne sais absolument pas où le problème peut être. D'une part, je soupçonne que ce doit être un problème de configuration d'une certaine sorte puisque le programme et la base de données sont les mêmes, d'autre part, cela n'a pas de sens puisque la configuration est identique.

Quelques données sur les serveurs:
Serveur de test:

  • Intel Core 2 Quad Q9400 à 2,66 GHz
  • 8 Go de RAM
  • Windows Server 2008 R2 Standard

Serveur de production:

  • Intel Xeon E5530 à 2,40 GHz
  • 5 Go de RAM
  • Windows Server 2012 R2 Standard

Edit: j'ai oublié de dire une chose importante: il y a plus de requêtes en cours d'exécution qui utilisent des clauses "WHERE ... IN" à part pour les clauses "offensantes". Ils sont exécutés rapidement sur les deux machines, ce qui me suggère qu'ils sont correctement optimisés par MySQL. Le fait que certaines requêtes soient optimisées lorsque d'autres ne le sont pas est un mystère pour moi, SI c'est le problème réel, dont je ne suis pas sûr.

Edit # 2: Voici le fichier de configuration pour les deux serveurs: http://pastebin.ca/2834906

Edit # 3: Voici l'EXPLAIN de l'une des requêtes lentes: https://mariadb.org/ea/v36zj L'EXPLAIN est exactement le même en test et en prod. La requête elle-même est ici: http://pastebin.com/VXgBxXmt Elle a été formatée avec une mise en forme automatique, donc peut-être n'est pas très claire. Comme vous pouvez le voir, est assez long et complexe. Il n'a pas été généré à la main, ils sont générés automatiquement sans code par le logiciel, qui utilise un dialecte du SQL standard avec certaines fonctions.

En outre, plus d'informations: nous avons temporairement corrigé le problème en réduisant les données sur le serveur de production et en supprimant la plupart des anciennes données de la base de données, qui ne seront pas utilisées. Ce n'est pas une solution, bien sûr, car nous avons également besoin des anciennes données, et ce sera un problème à l'avenir. La DB n'est pas si grande: la DB complète est de 1308 Mo, la version réduite actuellement en production est de 332 Mo.

MISE À JOUR: RÉSOLU ??

Je pense avoir résolu le problème. Je ne l'ai pas encore testé, car le serveur de production est actuellement utilisé, mais le problème possible était le paramètre "innodb_buffer_pool_size", qui était réglé sur 182M. En fait, la ligne dans le fichier de configuration affiche: innodb_buffer_pool_size = 321 ce qui est une erreur car il n'a pas le préfixe d'unité, donnant une valeur non valide (le minimum est 5242880 selon les documents), puis le mettant à la valeur précédente . Cette valeur dans le serveur de test a été définie sur le 321 Mo souhaité.

Comme je l'ai dit, je ne l'ai pas testé complètement. Ce que j'ai fait, c'est de réduire la valeur des tests et d'essayer l'application. Tout va plus lentement et la requête particulière que j'ai publiée s'exécute en 3 minutes.

J'ai mis à tester une valeur plus saine de 3Gb, ce que je ne sais pas si c'est une bonne idée, donc si quelqu'un a un commentaire à faire sur cette valeur, je l'apprécierai.

Mes conclusions, la "valeur saine" de 3Gb et les informations que j'ai utilisées pour cela proviennent de ces deux messages, en particulier le second:

Requête MySQL, 2 serveurs similaires, 2 minutes de différence dans les temps d'exécution

Quelle doit être la taille de mysql innodb_buffer_pool_size?

Je publierai les "vrais" résultats lorsque nous mettrons à jour les valeurs dans le serveur de production.

Merci à tous.

RESOLU

Nous avons donc finalement testé cela en prod, et c'est le problème que j'ai commenté précédemment. J'ai mis la valeur de innodb_buffer_pool_size dans 321M, qui est la valeur recommandée par le fournisseur du SDK que nous utilisons, même si, selon les liens précédents, il devrait s'agir de 3G pour une base de données de cette taille et de cette utilisation.

J'ai encore un doute, cependant: la valeur de 321 était une valeur invalide (trop petite), donc MySQL a pris une autre valeur. Je soupçonne qu'il a fallu le numéro valide précédent, 321M en test et 182M en prod, d'où les différences de vitesse. C'est juste par curiosité, mais j'aimerais savoir si c'est vrai.

Merci encore à tous pour l'aide.

juantxorena
la source
1
Les bases de données ont-elles même la même taille sur chaque serveur? Une base de données de test plus petite fonctionnera plus rapidement qu'une base de données de production plus grande. De plus, le serveur de test a presque le double de la RAM. À quoi ressemble l'utilisation de la mémoire?
1
Oui, la base de données est la même (en fait, un vidage de la base de données de production dans la base de données de test). Je n'ai pas encore vérifié l'utilisation de la mémoire sur le serveur de production, je vais maintenant l'informer.
1
Pourriez-vous extraire les mêmes statistiques de RAM de la boîte de test? Voyez-vous s'ils ont l'air très différents?
Chris S
2
Pouvez-vous publier un exemple de requête qui fonctionne très bien dans TEST mais qui est horrible dans PROD? De plus, veuillez exécuter le plan EXPLAIN sur la requête dans les deux systèmes et publier les résultats.
RolandoMySQLDBA
3
@juantxorena: vous devez rejeter les raisons, et ne rien supposer , de facile à difficile à vérifier. Étape 1 raison: différences dans le plan de requête. Exécutez EXPLAIN sur la production et sur le développement, vérifiez les différences (même minimes). Ajoutez ces informations et nous pourrons ensuite passer à l'étape 2.
jynus

Réponses:

4

Je suis peut-être en train de voler aveugle sur celui-ci, mais c'est parti ...

Dans votre question et vos commentaires, vous avez déclaré ce qui suit:

La version MySQL sur les deux serveurs est la même, même les fichiers de configuration sont les mêmes (la seule différence est le chemin des données et le fait que le serveur de production n'enregistre rien sauf les erreurs)

Oui, la base de données est la même (en fait, un vidage de la base de données de production dans la base de données de test).

Résultats similaires: 2,31 Go de manière stable

Vous devez fournir le plan EXPLAIN pour une requête. Étant donné que les données sont identiques, elles peuvent ne pas être nécessaires.

Il y a quelques choses qui peuvent être différentes

VOTRE PROCESSEUR

J'ai recherché l' Intel Core 2 Quad Q9400 à 2,66 GHz (TEST) et l' Intel Xeon E5530 à 2,40 GHz (PROD) et j'ai trouvé une différence.

  • CPU pour TEST a 4 threads
  • CPU pour PROD a 8 threads

On pourrait penser que PROD devrait être plus rapide.

Sa vitesse de bus interne peut être le goulot d'étranglement. Je soupçonne cela parce que TEST a une vitesse de bus plus élevée et un multiplicateur de bus de 8. Qu'est-ce qu'un multiplicateur de bus ?

La fréquence interne des microprocesseurs est généralement basée sur la fréquence du bus frontal. Pour calculer la fréquence interne, le processeur multiplie la fréquence du bus par un certain nombre, appelé multiplicateur d'horloge. Il est important de noter que pour le calcul, le CPU utilise la fréquence de bus réelle et non la fréquence de bus effective. Pour déterminer la fréquence réelle réelle du bus pour les processeurs qui utilisent des bus à double débit (AMD Athlon et Duron) et des bus à quadruple débit (tous les microprocesseurs Intel à partir de Pentium 4), la vitesse effective du bus doit être divisée par 2 pour AMD ou 4 pour Intel.

Sur cette base, la vitesse du bus interne pour AMD (TEST) est au moins 2 fois supérieure à Intel (PROD).

VOS STATISTIQUES D'INDICE

Depuis que vous avez chargé TEST avec les mêmes données, une chose a peut-être été ignorée. Je pense aux statistiques de l'indice. Pour TEST, les statistiques de l'indice seraient relativement nouvelles. Pour PROD, il peut être périmé si les tables indexées ont connu de nombreux INSERT, UPDATE et DELETE.

L'exécution d'un SELECT sur deux machines différentes avec une version mysql identique, des configurations mysql identiques, des ensembles de données identiques et même un matériel identique, pourrait être affectée par les statistiques d'index sur la table impliquée.

Je voudrais exécuter ANALYZE TABLE sur toutes les tables sur PROD et TEST, puis essayer de comparer les performances.

RolandoMySQLDBA
la source
Merci pour votre réponse complète. J'ai effectué l'ANALYZE TABLE sur toutes les tables et les temps d'exécution sont similaires. PROD est un peu plus lent dans la plupart des cas, un peu plus rapide dans d'autres, mais je parle de millisecondes, donc je ne pense pas que ce soit la cause. Je suis toujours en train de regarder.
juantxorena