JeuWeb - Crée ton jeu par navigateur
Réduire l'utilisation de ressources - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Réduire l'utilisation de ressources (/showthread.php?tid=3637)

Pages : 1 2


Réduire l'utilisation de ressources - Roworll - 03-02-2009

J'ai été confronté à un petit soucis lors de la création d'un module de gestion pour un site communautaire.
Je souhaitais, en utilisant un minimum de ressources, afficher des statistiques sur les guildes inscrites sur le site.

Ces statistiques devaient inclure
- Le nom de la guilde
- Le nombre total de membres
- La répartition des membres par classes
- Le niveau moyen de chaque classe représentées dans la guilde

Les structures des tables sont très simples dans cet exemple

Pour ma part, j'ai obtenu le résultat en trois requêtes distinctes (trois appels à la base de données), sans utiliser de requêtes imbriquées au autre fantaisies qui peuvent se révéler lourdes pour le serveur.
J'ai utilisé XML/XSLT pour mettre en forme les informations sur le poste client.

J'aimerai cependant savoir si vous voyez une solution plus efficace pour obtenir ce résultat.

Pour ceux qui veulent se lancer dans le "défi", voici le lien vers un fichier contenant le script de création des tables : Fichier SQL

Voici un lien vers le résultat :
[Image: stats.jpg]


RE: Réduire l'utilisation de ressources - Allwise - 03-02-2009

Salut, les requêtes imbriquées et les jointures ne sont pas des fantaisies...
Elles tirent parti des index de table, pour peu qu'on en ait mis, et sont très rapides. Certainement plus rapides que 3 requêtes distinctes, qui requièrent 3 échanges serveur web / serveur base de données.
De plus, avec ta méthode, chacune de tes requêtes parcoure TOUS les enregistrements des tes 3 tables.
Supposons que tu aies 1000 membres, 5 classes et 10 guildes, ça te fait parcourir toutes les classes et toutes les guildes pour chaque membre.

Avec des jointures et des index ( qui manquent dans ton script SQL pour les champs exe_membres.membre_guilde_id et exe_membres.membre_classe_id), tu aurais parcouru une classe et une guilde pour chaque membre. Deux jointures dans une requête en plus, c'est très light...

A titre d'exemple, un pote a fait une requête avec 6 jointures et 2 requêtes imbriquées. Il manquait des index et certaines conditions de jointures étaient mal écrites. Résultat : ~ 1 minute d'exécution. Après optimisations => 1 seconde.


RE: Réduire l'utilisation de ressources - Astrea - 03-02-2009

Tout à fait, les jointures dans une requête SQL sont plus rapide que 3 requêtes successives.
Même si ça ressemble plus à un pavé qu'à une requête dans certains cas, il est clair que de la dissociée alourdirait les transferts et donc la durée. Puis SQL est fait et optimisé pour traiter au mieux chaque requête.

De plus, en faisant 3 SELECT tu as aussi 3 mysql_fetch_assoc(), tu te retrouve avec 6 traitements au lieu de 2 avec une requête bien faites (certes plus longue qu'une requête basique mais au final plus rentable).


RE: Réduire l'utilisation de ressources - Roworll - 03-02-2009

Je tiens à vous rassurer, je ne suis pas un débutant en ce qui concerne les requêtes SQL même si j'ai plus l'habitude de travailler sur SQL Server que MySQL. Même si INNODb est assez performant, on est encore loin des avantages d'un SGDB pro avec la notion de statistiques, covered indexes, query plans, etc.
Bref...
Citation :les jointures dans une requête SQL sont plus rapide que 3 requêtes successives.
Je suis bien d'accord mais trouver une requête unifiée pour renvoyer ce que je cherche à obtenir est loin d'être aisé sans construire des SELECT imbriqués qui sont autant de sous requêtes

De plus, les résultats que je veux concernent bien tous les enregistrements de toutes les tables.
- La table de guilde sera parcourue dans son intégralité
- Idem pour la table des classes
- La table des membres sera au moins parcourues par les pointeurs MySQL le temps de faire les agrégations.

Je demande vraiment à voir les avantages de la requête unifiée dans ce cas particulier et surtout sa structure.


RE: Réduire l'utilisation de ressources - Sephi-Chan - 03-02-2009

Si la jointure induit des traitements de tableau derrière, ça ne vaut forcément pas la peine. Smile


Sephi-Chan


RE: Réduire l'utilisation de ressources - Argorate - 04-02-2009

(03-02-2009, 07:30 PM)Roworll a écrit : Je suis bien d'accord mais trouver une requête unifiée pour renvoyer ce que je cherche à obtenir est loin d'être aisé sans construire des SELECT imbriqués qui sont autant de sous requêtes

Je demande vraiment à voir les avantages de la requête unifiée dans ce cas particulier et surtout sa structure.
Je ne sais pas si en l'occurrence c'est applicable, mais il est préférable d'avoir une sous requête que deux, trois requêtes séparés, car tu as deux ou trois connexions à ta BDD au lieu d'une, donc tu perd en temps d'exec.


RE: Réduire l'utilisation de ressources - Wells - 04-02-2009

Utilise tu des vue ou des procédures stockées pour faire ta requête?


RE: Réduire l'utilisation de ressources - Anthor - 04-02-2009

Peut-être qu'en ayant les requêtes que tu as fait ça serait plus simple de t'aider ? Non ?


RE: Réduire l'utilisation de ressources - wild-D - 04-02-2009

la requête de base elle est facile; il doit avoir une truc du genre:
SELECT `membre_guilde_id` , `membre_classe_id` , COUNT( `membre_guilde_id` ) AS `nbr` , AVG( `membre_niveau` ) AS `moy`
FROM `exe_membres`
WHERE 1
GROUP BY `membre_guilde_id` , `membre_classe_id`
(edit: et pour les 2 autre ben il récupère ses 2 autre table avec un SELECT *)

résoudre les id->intitulé est pas trop sorcier, par contre, j'ai voulu regarder comment on faisait pour faire un "tableau croisé dynamique" en mysql ça parait franchement pas "agréable" ou en tout cas j'ai pas trouvé comment on faisait ça simplement. (pourtant ça paraitrait un truc standard pour de la manipulation de données)


RE: Réduire l'utilisation de ressources - Roworll - 04-02-2009

Pas de procédures stockées.
Le serveur de prod que j'utilise ne le supporte pas.

Ensuite, mes requêtes sont de simple extractions de table.

Code PHP :
<?php 
* SELECT guilde_id, guilde_nom FROM exe_guildes

* SELECT membre_guilde_id, COUNT(*) as mbrtot, membre_classe_id, SUM(membre_niveau) as mbravg
FROM exe_membres
GROUP BY membre_guilde_id
, membre_classe_id

* SELECT classe_id, classe_nom from exe_classes

J'ai mis à dispo mon jeu de test MySQL (structure des tables + contenu) dans mon post original.
Je me base sur ces trois requêtes simples pour sortir le tableau que j'ai mis en lien en début de sujet.
Trois requêtes, pas de calculs sur le serveur PHP, pas de parcours imbriqué des données dans le code PHP, tout réalisé en local sur le client via XSLT.

Pour être clair, ce n'est pas de l'aide que je recherche. Je veux comparer nos approches et voir si certains parmi vous ont une solution plus efficace que la mienne.
Il n'y a pas que la requête à analyser mais aussi tout ce qui va derrière, du traitement des données SQL au rendu de la page. Je souhaite faire un comparatif entre ma méthode et les vôtres sur ce problème particulier.

Montrez moi la requêtes que vous auriez utilisé par exemple, avec ou sans sous requêtes, avec ou sans jointures. Quel code auriez-vous utilisé pour traiter le rendu d'informations ? Etc.

La question que je posais en tout début est, je le rappelle :
"J'aimerai savoir si vous voyez une solution plus efficace pour obtenir ce résultat."

Si oui, démontrez le.

[edit]
Pour info, en local, sur mon vieux laptop, je génère la page en 0.013 s en moyenne, les requêtes représentant 0.0006 secondes
Sur mon serveur c'est plutôt de l'ordre de 0.007 s la page et 0.002 s les requêtes.