Bug #4728

Performance trouble on tickets linked to computers

Added by moyo about 6 years ago. Updated about 6 years ago.

Status:ClosedStart date:12/17/2013
Priority:NormalDue date:
Assignee:moyo% Done:

100%

Category:Inventory
Target version:0.84.4

Description

Bonjour,

Nous utilisons GLPI sur une base très grosse (plus de 1,5 millions de tickets / 30 000 ordinateurs) et nous avons constaté des performances très mauvaises au fur et à mesure du temps lors de l'ouverture d'un élément d'inventaire (imprimante, moniteur, ...). Récemment le temps d'ouverture d'une fiche d'un de ces éléments pouvait dépasser les 30 secondes sur une machine solide ( quad core / 8go de RAM / disque SSD hébergeant la base MySQL 5 / Linux).

Le problème a rapidement été identifié grâce au mode debug de GLPI : une unique requête était responsable de ces temps de chargement.

Après analyse du code, si je ne me trompe pas, cette requête sert uniquement à compter le nombre de tickets liés à un élément d'inventaire lorsque celui-ci est relié à un ordinateur lui même relié à un ticket. (ticket => ordinateur => élément X, alors indice incrémenté de 1 sur la fiche de cet élément pour l'onglet "Ticket").

Cette requête, pour une imprimante par exemple, est de la forme suivante :
SELECT COUNT AS cpt
FROM `glpi_tickets`
WHERE (`itemtype`,`items_id`) IN (SELECT 'Computer', `computers_id`
FROM `glpi_computers_items`
WHERE `itemtype` = 'Printer' AND `items_id` = '13282');

Je comprends bien l'avantage d'un point de vue code pour l'utilisation d'une sous requête (la classe Printer renvoie le bout de requête qui indique quels sont ses liens) mais d'un point de vue MySQL les performances sont catastrophiques : pour les 1,5 millions de tickets en base, il exécute la sous requête autant de fois pour voir quel(s) match(s) il y a (c'est ma supposition, mais vu les temps de réponse ça semble coller). Alors que le pire est que la sous requête ne renvoie aucun résultat (l'imprimante n'est relié à aucun ordinateur).

En reformulant la requête en :
SELECT COUNT AS cpt
FROM `glpi_tickets` gt
LEFT JOIN glpi_computers_items gci ON ( gci.computers_id = gt.items_id)
WHERE gt.itemtype = 'Computer' AND gci.items_id = 13282 AND gci.itemtype='Printer';

On passe à un temps d'exécution nul pour un résultat (si je ne me trompe pas) identique.

À partir de là j'ai modifié le code de GLPI pour utiliser cette requête : j'ai ajouté une nouvelle fonction à la classe commondbtm qui compte le nombre de tickets liés à l'élément (la fonction initiale n'étant visiblement que utilisée à cette fin et non pour voir les liens avec d'autres éléments que les ordinateurs).

Je n'ai appliquée l'optimisation qu'a la classe ticket, mon installation n'utilisant pas les "problèmes", mais je suppose que les lenteurs seraient reproductibles pour les problèmes si ma base en avait beaucoup. Il suffirait dans ce cas d'utiliser la même solution en appelant la nouvelle fonction.

Pour exemple voici les résultats avant et après application du patch:
https://cloud.dedikewl.fr/public.php?service=files&t=3299aea891f8cfdd61a8991556bca2e1
https://cloud.dedikewl.fr/public.php?service=files&t=61fe2bdbceee92393e7c6ea0bf0a8e75

Le patch est pour la version 0.83 mais je l'ai testé sur la 0.84 et il semble fonctionner parfaitement aussi.

Est-ce que j'ai raté quelque chose au niveau de l'analyse/correction du problème ou bien cette optimisation est correcte ?

Cordialement

Régis Damongeot

Associated revisions

Revision 22309
Added by moyo about 6 years ago

[0.84] Performance trouble on tickets linked to computers fixed #4728

Revision 22310
Added by moyo about 6 years ago

Performance trouble on tickets linked to computers fixed #4728

History

#1 Updated by moyo about 6 years ago

  • Status changed from New to Resolved
  • % Done changed from 0 to 100

Applied in changeset r22309.

#2 Updated by moyo about 6 years ago

Applied in changeset r22310.

#3 Updated by moyo about 6 years ago

  • Status changed from Resolved to Closed

Also available in: Atom PDF