8
votes

Comment rendre MySQL utiliser les ressources système disponibles ou trouver "le vrai problème"?

Ceci est un serveur MySQL 5.0.26, en cours d'exécution sur SUSE Enterprise 10. Cela peut être une question Serverfault.

L'interface utilisateur Web qui utilise ces requêtes particulières (ci-dessous) montre parfois 30 + forte>, même jusqu'à 120+ secondes forte> au pire, pour générer les pages impliquées . P>

sur le développement, lorsque les requêtes sont exécutées seules, elles prennent jusqu'à 20 secondes sur la première exécution (sans cache de requête activée) mais n'importe où de 2 à 7 secondes après cela - je suppose parce que les tables et Les index impliqués ont été placés dans la RAM. P>

De ce que je peux dire, les temps de chargement les plus longs sont causés par Verrouillage de lecture / mise à jour forte>. Ce sont des tables fortes> myisam forts. Cela ressemble donc à une longue mise à jour, suivie de quelques 7 secondes requêtes, et ils s'ajoutent juste. Et je vais bien avec cette explication. P>

Ce que je ne vais pas bien, c'est que MySQL ne semble pas utiliser le matériel qu'il est sur strong>, et pendant que le goulot d'étranglement semble être la base de données, i Je ne comprends pas pourquoi em>. P>

Je dirais «lancer plus de matériel de référence», mais nous avons fait em> et cela ne semble pas avoir changé la situation. Affichage d'un «haut» pendant les moments les plus lents ne montre jamais beaucoup de CPU ou d'utilisation de la mémoire par mysqld code>, comme si le serveur n'a aucun problème à tout - mais alors, pourquoi les requêtes prennent-elles si longtemps? P>

Comment puis-je faire utiliser MySQL l'utilisation de la merde de ce matériel ou découvrir ce que je fais mal? H2>

Détails supplémentaires: strong> P >

sur l'onglet "Memory Health" de l'administrateur MySQL (pour Windows), le tampon de clé est inférieur à 1 / 8ème utilisé - de sorte que tous les index doivent être en RAM. Je peux fournir un coup d'écran de tous les graphiques qui pourraient aider. P>

si désespéré de résoudre ce problème. Il suffit de dire qu'il y a du code hérité "générer" ces requêtes et ils ont à peu près collé la façon dont ils sont. J'ai essayé chaque combinaison d'index sur les tables impliquées, mais toutes les suggestions sont les bienvenues. p>

Voici la déclaration actuelle de la table de création du développement (la touche "expérimentale" que j'ai ajoutée, semble aider un peu em>, pour l'exemple de requête uniquement): p> xxx pré>

et une des requêtes ridicules en question: p> xxx pré>

my.cnf - "[mysqld] 'section" h3> xxx pré>

p>

expliquer la requête ci-dessus, sans index supplémentaire h3>

: p> xxx pré>

expliquer ci-dessus , avec l'index "expérimental": h3> xxx pré>

index de l'enregistrement_task; h3> xxx pré>

solution? h2>

Je pense que j'ai peut-être résolu le problème, que pour certains semblera si gênant évident em>, mais était négligé jusqu'à présent: la définition de inscription.id code> est: xxx pré>

tandis que le enregistrement_task.parent_id code> (fk sur inscription.id code>) était: p> xxx PRE>

Changement de cette via: P>

alter table `sugarcrm401`.`registration_task` change `parent_id` `parent_id` bigint(20) UNSIGNED NOT NULL;


3 commentaires

Je sais que la définition de la table et les requêtes sont un peu wtf-y ou insensées. Je suis d'accord . Je ne l'ai pas fait, mais je dois le réparer . Il est venu avec le travail.


Ha! Vous pouvez (ou peut ne pas) trouver cet humour. forum.percona.com/index.php/mv/msg/843 / 3328


Je trouve considère que l'humour et laissez-moi vous dire pourquoi: le deuxième ou dernier message sur ce thread est à partir de 2008. Le post le plus récent, soulignant la même chose que j'ai découvert, vient de Avril 2010. J'aurais aimé avoir une "réponse à un thread" ... "Email, car Je suis 'anon_login'.


4 Réponses :


0
votes

Veuillez indiquer Afficher les index résultant de vos tables. Recommandation générique que je peux donner maintenant est de:

  • Ajouter des index séparés sur les champs Inscription_Task: Assigned_user_id, parent_id, date_due
  • Ajouter un index sur inscription.field060
  • supprimer une partie de la requête "et inscription.field001 comme"% "et enregistrement_task.name comme"% "" - il est inutile. % signifie n'importe quel nombre de caractères

    Après cela, postez-vous à nouveau.


4 commentaires

Si je mets date_due au début de l'index "expérimental", expliquez les considérants, mais ne l'utilise pas du tout, optant plutôt pour l'index d'origine IDX_REG_TASK_P . Avez-vous des recommandations spécifiques sur l'obtention de cela pour travailler?


J'ai mis à jour mon commentaire. S'il vous plaît faire comme il l'a dit et faire rapport. Nous verrons ce que nous pouvons faire.


En ce qui concerne l'élimination d'une partie de la requête - elle est automatiquement générée par ce système horrible, de type Frankenstein. Je vais séparer les index et vous expliquer et vous revenir à vous.


J'ai ajouté des index individuels qui, comme je m'y attendais, ne montre aucune différence dans la préférence de MySQLS de l'indice à utiliser - IDX_REG_TASK_P ou TCG_Experimental si disponible. En outre, il existe déjà un indice sur le «Field060», appelé «GBL», qui est utilisé et optimal, comme vous pouvez le constater par les résultats d'explication indiquant une seule ligne examinée pour cette table.



1
votes

Lorsque vous avez une requête qui dit! = C'est invariablement être lent. Et notez que l'index n'est pas utilisé sur cette partie de la requête, même si le champ d'état est sur deux index différents!

Vous ne voulez pas avoir de champ de Varcharchar (255) entièrement indexé et de l'avoir dans le cadre de deux clés différentes consiste à rendre vos mises à jour très très lentes. Avoir un total de cinq index consiste simplement à ajouter au désordre. Si vous effectuez des éléments de sélection au même moment où une mise à jour se produit, cela va vraiment prendre beaucoup de temps comme vous l'avez déjà vu.

Ce que vous voudrez peut-être faire est d'indexer une petite partie de votre champ de 255 caractères. Mieux encore, vous voudrez peut-être utiliser un entier (StatusCode) au lieu de statut ici. Cela accélérera beaucoup de choses.

Avoir plus de mémoire ou plus de CPU ne va pas aider ici. Avoir un disque dur supplémentaire vous donne un boost de 20 à 30% de vitesse. Mais vous pouvez faire la même requête complète en moins d'une seconde en réorganisant simplement vos index.


6 commentaires

En ce qui concerne le changement de «statut», je ne peux malheureusement pas changer les champs eux-mêmes, ni ce qui les contient. Je suis très très intéressé par des suggestions d'organisation d'index spécifiques. Si je pouvais obtenir cette requête d'exécution à moins d'une seconde en modifiant seul des index, je vous enverrai une boîte à chaussures de goodies dans le courrier!


Eh bien, vous pouvez commencer à supprimer tous les index qui ne sont pas utilisés. L'explique montre ce qui est utilisé et ce qui n'est pas utilisé. Cela accélérera les inserts / mises à jour, ce qui signifie que vos requêtes sélectionnées ne doivent plus attendre sur eux pour finir. Que lui-même vous donnera un grand boost.


Avez-vous essayé: où inscrivez-vous_task.deletted = 0 et (enregistrement_task.status! = 'Terminé' et inscription.field001 comme '%' et inscription_task.name comme '%' et enregistrement.field060 comme 'gn001472%')


Les autres index sont tous des résultats d'accélération des requêtes spécifiques / jointures dans d'autres endroits de l'application. En ce qui concerne le réaménagement de l'endroit où, expliquer les modifications de l'ordre des tables observées, mais ne modifie pas les index utilisés, ou nombre de lignes numérisées sur la table d'enregistrement_task, la seule numérisation de plus d'une seule ligne. Donc, si mes écritures sont en train de verrouiller d'autres lectures, se déplacerait vers une réplication Master-Ecris / esclave (s) -Pour-Lists améliorent réellement les performances? Comment les mises à jour sur un travail d'esclave?


La réplication pourrait aider, passant à InnoDB peut également aider votre performance.


Eh bien, si les autres index sont nécessaires pour d'autres requêtes. Ce que vous pouvez faire est de réduire le nombre d'index d'octets que j'ai mentionné précédemment. Pour les champs de charcuterie longue ou de varchar, il vous suffit d'indexer les 5-10 premiers caractères. Vous obtiendrez à peu près la même cardinalité qu'un indice sur l'ensemble du champ 255.



1
votes

Vous devriez être capable d'optimiser cela avec des index appropriés. En tant que fractaliseur, vous avez besoin d'index sur des colonnes de jointure et des colonnes de votre relevé de votre relevé. Il suffit de les ajouter à un seul index ne résoudra pas votre problème. Quels index avez-vous sur l'enregistrement?


3 commentaires

Premièrement, j'ai des champs très soigneusement ajoutés dans l'ordre de leur utilisation par le moteur au plus grand index que vous voyez. Je n'ai pas simplement ajouté "les tous" à un index. Il existe également d'autres index sur la table principale. En ce qui concerne les index sur enregistrement , il y en a quelques-uns, mais je crois comprendre que MySQL n'utilisera qu'un seul index lors d'une requête et que la majorité des opérations sont effectuées sur le enregistrement_task < / Code> Tableau, je me concentrais là-bas.


Désolé, ne voulait pas sembler dur, renforce simplement le point. J'étais curieux de la table d'inscription, comme il y a peut-être un moyen d'optimiser en restructurant votre requête. Vous utilisez une jointure à gauche, voulez-vous vraiment afficher des tâches qui n'ont aucun utilisateur ou enregistrement?


Eh bien, comme je l'ai mentionné dans la paroi géante du texte, la modification des questions n'est pas une grande partie de l'option, en tenant compte de ceux-ci étant automatiquement générés par le logiciel. Je pense que j'ai peut-être trouvé une solution et j'ai ajouté encore plus de texte au mur ci-dessus.



0
votes

La réponse à la majorité du problème était celle de mon édition:

la définition de enregistrement.id est: xxx < P> Bien que le enregistrement_task.parent_id (fk to enregistrement.id ) était: xxx

changer cette via: < / p> xxx

... fait que l'explication ne montre que les lignes 25 examinées, où il était précédemment 651 903 , et 103,345 Il est préférable de forcer une indexation folle.

avais-je posté la définition de la table de l'enregistrement , je suis sûr que quelqu'un pourrait l'avoir repéré.


Ceci, cependant, 't résoudre le problème complètement. Je suis sûr que je laisse certains détails, mais ce projet est loin derrière moi à ce stade. Merci beaucoup pour tout votre temps et vos réponses!


0 commentaires