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.
la source
Réponses:
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:
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.
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 ?
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.
la source