Amélioration des performances & d'exécution des requêtes

Résolu/Fermé
guedo Messages postés 77 Date d'inscription mercredi 26 novembre 2014 Statut Membre Dernière intervention 10 avril 2019 - 9 avril 2019 à 00:15
guedo Messages postés 77 Date d'inscription mercredi 26 novembre 2014 Statut Membre Dernière intervention 10 avril 2019 - 10 avril 2019 à 17:34
Bonjour / Bonsoir a toute la communauté,

Cela fait un moment que je n'ai pas fait appel à vous, car de manière générale, les choses ont déjà été dites et n'ont pas besoin d'être répété pour être comprise Lol.

Le sujet de ma demande, concerne à mon avis, un grand nombre de développeurs car j'ai déjà trouvé pas mal de Forum traitant l'objet de mon objectif à réaliser avec systématiquement la même solution.

Je possède une base de données composer de différentes tables sans avoir besoin de rentrer les détails mais qui sont reliées en elles-mêmes grâce à des ID.

Prenons l'exemple d'une table de "contact" qui serait identifiés par des ID CONTACT et une table "status" qui serait identifié par des ID STATUS qui eux concernent des ID CONTACT.

Dans la logique des choses on prend la base qu'un ID CONTACT peut se voir attribuer plusieurs ID STATUS tandis qu'un ID STATUS ne va concerner qu'un seul ID CONTACT.

Vous comprenez tout de suite (pour ceux qui ont une base minimum en My Sql) que dans mes requêtes de sélection, je vais devoir récupérer mon ID CONTACT avec le status le plus récent qui lui a été attribués.

Pour ce faire la solution que j'ai trouvée et que j'ai donc mis en place c'est de faire un ;

SELECT 
* 
FROM 
`contact` c 
INNER JOIN `status` s 
ON 
c.`ID_CONTACT`=s.`ID_CONTACT` 
AND s.`ID_STATUS IN (SELECT MAX(s2.`ID_STATUS`) FROM `status` s2 WHERE s.`ID_CONTACT`=s2.`ID_CONTACT`)


Pour tout vous dire, cette requête est logique, peut être écrite de plusieurs manières différentes et fonctionne à merveille ce jusqu'à ce qu'elle commence à ralentir le système, car au final, la structure de cette base de données, fait que pour obtenir des COUNTS() ou des SELECT (pour de la consultation de données ou des calculs de KPI) vous êtes obligés de faire parcourir toute la base par votre requête afin de mettre en correspondance chaque ID CONTACT.

Aujourd'hui, je me rend compte que plus ma base de donnée s'alourdit, plus mon application web prend du temp à charger la DATA car elle doit parcourir plus de lignes dans la base pour obtenir le résultat final.

Avez-vous déjà rencontrés et/ou traités ce problème ?

Merci d'avance pour vos participations, toutes observations est bonne à soumettre.
Celui qui pose une question risque de passer pour un sot. Celui qui n’en pose pas est sûr de le rester.

PS: le but de rajouter une ligne dans la table "status" en relation avec un ID_CONTACT plutôt que d'écraser et de ne conserver qu'une seule ligne c'est de pouvoir conserver l'historique de tous les statut par lesquells les contacts sont passés.

À vos claviers ... ;)

2 réponses

Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
9 avril 2019 à 11:17
Bonjour,

As-tu pensé à créer un index sur ID_CONTACT dans ta table Status ?

Xavier
1
guedo Messages postés 77 Date d'inscription mercredi 26 novembre 2014 Statut Membre Dernière intervention 10 avril 2019 1
9 avril 2019 à 11:44
Bonjour Xavier,

Non, dans ma table status, j'ai un INDEX appliqué sur l'ID STATUS pour le définir comme étant une clé primaire en auto increment.

Donc la procédure serait d'ajouter à ma table un index de type INDEX uniquement sur la colonne ID_STATUS, (en plus de l'index de clé primaire).

Le fait de rajouter dans la table status un index sur l'ID CONTACT va me permettre d'adapter la structure de ma requête c'est bien sa ?
0
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
9 avril 2019 à 13:16
Re,

Pas besoin d'index sur la clef primaire, elle est indexée par nature.
Par contre, l'index sur ID_CONTACT est indispensable. Tu n'as pas besoin de changer ta requête, c'est totalement transparent de ce point de vue-là.

Xavier
0
guedo Messages postés 77 Date d'inscription mercredi 26 novembre 2014 Statut Membre Dernière intervention 10 avril 2019 1
10 avril 2019 à 17:34
Merci pour cette solution, je n'avais pas penser que l'INDEX soit indispensable à déclarer.
Des chargement de pages sur mon application web qui pouvait aller jusqu'à plusieurs minutes se retrouvent charger en moins de 3 secondes ... c'est une merveille :)
0
jee pee Messages postés 39637 Date d'inscription mercredi 2 mai 2007 Statut Modérateur Dernière intervention 25 avril 2024 9 235
9 avril 2019 à 12:02
Bonjour,

L'index est effectivement une bonne idée.

Si le Status est souvent utilisé avec les données Contact une solution serait d'intégrer dans cette dernière table le Status courant. Cela simplifierait notablement la recherche.

Cdlt
0
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
9 avril 2019 à 13:20
Effectivement, garder d'un côté l'historique, et de l'autre la valeur courante permet de conserver le meilleur des deux mécanismes :)
Par contre il faut être sûr que le code de fasse jamais d'UPDATE direct sur la table CONTACT, l'idéal étant de coder une procédure stockée de mise à jour du statut qui gère elle-même, d'un côté l'UPDATE contact, de l'autre l'INSERT status.
0