Gestion des prérequis - 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 : Gestion des prérequis (/showthread.php?tid=5419) |
RE: Gestion des prérequis - Jeckel - 16-05-2011 Bon, pour commencer, optimiser la base de données : Je suis un peu maniaque sur les bords, donc j'ai supprimé la clé inutile sur bati_user pour la remplacer par une clé double (user / bati), les clés, sont en bigint et non-singé (vous n'aurez jamais de clé négative), enfin j'ai renommé les champs pour facilité les jointures (vous verrez plus bas). Bon, j'aurais pu aussi rajouter les contraintes de clé étrangère, mais ça n'optimise en rien les select, ça sécurise juste les insert et update, donc je vous les laisse. La nouvelle base de test :
Bon ensuite, deux petites choses : 1. le SELECT * c'est bien quand on est sûr de vouloir vraiment tous les champs, mais avec un *, on ne sait jamais ce qu'on remonte, et s'il y a trop de champs, ça ralenti le résultat, il vaut donc mieux préciser à chaque fois les champs que l'on souhaite récupérer. 2. Les requêtes imbriqués c'est lent, terriblement lent, car selon comment elles sont mise en place, elle peuvent être chacune appelée pour chaque ligne du premier select... donc à supprimer. Ca donne ceci : Les bâtiments déjà construit pour l'utilisateur 1 :
Les bâtiments qui restent à construire :
La requête se traduisant par "les bâtiments qui n'existent pas chez l'utilisateur", plutôt que le NOT IN(SELECT …) utilisez le LEFT JOIN … WHERE id IS NULLEnfin les bâtiments dont les prérequis (s'il y en a) peuvent être construit :
Un dernier point, le OR dans la clause WHERE, c'est aussi un truc qui a tendance à ralentir, alors on va essayer de l'enlever en faisant l'Union de deux requêtes, les bâtiments sans prérequis et ceux dont les prérequis sont valide :
Voilà, on pourra difficilement faire plus rapide… Ensuite, histoire d'essayer d'utiliser le cache de la base de données, je conseillerai de créer une vue avec cette requête (en ajoutant l'utilisateur dans le résultat) Reste un cas qui n'est pas pris en compte dans cette requête : le cas où deux bâtiments sont requis pour la construction d'un troisième ! Après relecture, le seul point de ralentissement qui reste dans la requête c'est ce morceau là :
RE: Gestion des prérequis - Myrina - 16-05-2011 (16-05-2011, 08:05 AM)Jeckel a écrit : Reste un cas qui n'est pas pris en compte dans cette requête : le cas où deux bâtiments sont requis pour la construction d'un troisièmeDonc, avec le jeu d'essai, le bâtiment 5 est dit constructible ou non avec ta requête? RE: Gestion des prérequis - Jeckel - 16-05-2011 Haha, je n'avais pas vu qu'il était là celui-là... Heu, là j'en sais rien, je ne peux pas faire de test ici (au taf) Mais à vu de nez, vu qu'au moins un des prérequis est bon, je pense que le bâtiment ressort comme constructible... Ce cas là, sans requête imbriqué, je crois que ce n'est pas faisable... (ou alors avec des fonctions stockées, mais c'est pas toujours mieux) Bon, j'aime pas rester sur une colle, j'vais y réfléchir et je vous file ce que j'ai trouvé dans les jours qui viennent, de toute façon, c'est le genre de truc que je dois résoudre pour mon propre projet, vu que j'ai une évol similaire pour la prochaine version d'Eden-5. RE: Gestion des prérequis - Myrina - 16-05-2011 (16-05-2011, 02:43 PM)Jeckel a écrit : Bon, j'aime pas rester sur une colle, j'vais y réfléchir et je vous file ce que j'ai trouvé dans les jours qui viennent, de toute façon, c'est le genre de truc que je dois résoudre pour mon propre projet, vu que j'ai une évol similaire pour la prochaine version d'Eden-5.Vivement à dans quelques jours alors RE: Gestion des prérequis - Jeckel - 16-05-2011 Sinon, si on veut être complet, il faudrait rajouter le fait que, souvent, les prérequis ne sont pas tous de même nature.. Ici, la construction d'un bâtiment n'a de pré-requis que d'autres bâtiments, mais il peut y avoir aussi des recherches par exemple, ou encore des tokens... Pour construire le bâtiment du pouvoir absolu il faut avoir construire 3 autres bâtiments, terminé la recherche du savoir absolu et être en possession du Talisman de Rocledur... par exemple ;-) (et tout ça en SQL ? heu... p'tet pas quand même, encore que.. ;-)) RE: Gestion des prérequis - Myrina - 16-05-2011 (16-05-2011, 03:29 PM)Jeckel a écrit : (et tout ça en SQL ? heu... p'tet pas quand même, encore que.. ;-))Bin si, j'ai prévu, avec le même SELECT, d'avoir comme prérequis: - un bâtiment, - un recherche, - un résultat de quête, - un personnage, ... RE: Gestion des prérequis - Jeckel - 16-05-2011 Je précise : sans requête imbriquée RE: Gestion des prérequis - Ter Rowan - 16-05-2011 (16-05-2011, 03:29 PM)Jeckel a écrit : Sinon, si on veut être complet, il faudrait rajouter le fait que, souvent, les prérequis ne sont pas tous de même nature.. y a encore plus compliqué (et je planche dessus) là tu ne décris que des ET (il faut A et B et C ...) mais on peut aussi avoir des OU : il faut avoir construit 3 autres bâtiments Et (avoir trouvé le savoir absolu ou être en possession du Talisman de Rocledur) et là c'est le drame... Je pense qu'on sort du SQL pour passer au langage... Eventuellement on pourrait même mettre en base les éléments répondant au prérequis par utilisateur, pour éviter les calculs, avec une mise à jour lorsqu'un prérequis est validé RE: Gestion des prérequis - niahoo - 16-05-2011 ça demanderait une table avec une ligne pour chaque joueur * chaque bâtiment. Et pouruqoi pas faire deux requêtes ? la première sur une table id_batiment | id_type_de_prerequis | id_correspondant et la suivante, construite dynamiquement avec les jointures qui vont bien. C'est simple, évolutif et ça vous permet de faire peu de requêtes puisque vous semblez vouloir en faire le moins possible :p RE: Gestion des prérequis - Jeckel - 17-05-2011 @Ter Rowan : j'osais pas en parler, je risque d'avoir des trucs dans ce genre là aussi, mais entre le stockage de la règle en base de donnée (comme ici la table des prérequis) et la validation, je pense qu'effectivement, en pur SQL ça risque d'être chaud... à moins de passer par des tables intermédiaires, des triggers pour mettre à jour ces tables quand un bâtiment est construit, etc... @niahoo : le but n'est pas spécialement de faire le moins de requête possible, mais plutôt de faire l'opération avec un temps le plus court possible. Pour ça, il y a des choses a éviter en SQL : - les OR dans un WHERE par exemple font perdre une bonne partie des avantages liés aux index, - les requêtes imbriqués sont générale exécuté pour chaque enregistrement de la requête parente (donc gros ralentissement), - enfin les jointure gauche (LEFT JOIN) sont à utiliser judicieusement car elles ont tendance à multiplier énormément le nombre d'enregistrement à traiter par le WHERE, il faut donc les utiliser sur des index et de manière à limiter les résultats. - dernier point, l'ordre des tables peut aussi jouer sur les perfs. Dans mon dernier exemple par exemple, faire un UNION, c'est presque comme faire deux requêtes finalement. Sinon, personnellement, je ne suis pas partisan de la requête construite dynamiquement, c'est en général source de failles de sécurité, peu performant, et souvent tu perds plus de temps à construire cette requête, en plus tu contrôles du coup beaucoup les performances de ta requête. C'est valable pour des petits trucs, mais là, si l'on prend l'exemple de Ter Rowan, tu peux rapidement généré une requête usine à gaz je pense. Mais bon, c'est plus un avis personnel là. |