fingolfin Posté 31 Juillet 2007 Posté 31 Juillet 2007 (modifié) Bien le bonjour, Voilà, je suis en ce moment en train de faire un jeu, j'en suis à la partie d'affichage des productions du joueur dans une certaine zone, le problème étant que chaque bâtiment est unique (il n'y a pas 100 moulins mais 100 * 1 moulins), ce qui m'oblige à compter le nombre de moulins, champs ... Mais voilà, en plus que chaque bâtiment soit unique, il possède un état de sa structure qui peut varié s'il a subit des dégâts liés à des combats ou à des catastrophes naturelles, mon problème est donc que je me retrouve avec une requête faisant 6 COUNT rien que pour deux bâtiments, sachant que j'aurais dans les 10 bâtiments au final, j'effectuerais donc une trentaine de COUNT, ce qui me paraît être assez lourd pour mon hébergement (et pas optimisé du tout), aussi j'aimerai savoir si vous connaissiez un autre moyen pour avoir le même résultat que ces 30 COUNT sans en faire 30 justement Voici à quoi ressemble ma requête actuellement (je précise qu'elle marche ce n'est donc pas le problème) $donnees_batiment = mysql_query("SELECT (SELECT COUNT(*) FROM batiment WHERE nom = 'moulin' AND etat = 'neuf') AS moulin_neuf, (SELECT COUNT(*) FROM batiment WHERE nom = 'champ' AND etat = 'neuf') AS champ_neuf, (SELECT COUNT(*) FROM batiment WHERE nom = 'champ' AND etat = 'abime') AS champ_abime, (SELECT COUNT(*) FROM batiment WHERE nom = 'moulin' AND etat = 'abime') AS moulin_abime, (SELECT COUNT(*) FROM batiment WHERE nom = 'champ' AND etat = 'detruit') AS champ_detruit, (SELECT COUNT(*) FROM batiment WHERE nom = 'moulin' AND etat = 'detruit') AS moulin_detruit FROM batiment WHERE id_region = '" . $_SESSION['region'] . "' AND id_territoire = '" . $_SESSION['territoire'] . "' AND type_zone = 'plaine'")or die(mysql_error()); Voici la structure de la table en question : CREATE TABLE `batiment` ( `id` mediumint(9) NOT NULL auto_increment, `id_region` mediumint(9) NOT NULL, `id_territoire` mediumint(9) NOT NULL, `type_zone` varchar(30) NOT NULL, `nom` varchar(30) NOT NULL, `etat` varchar(30) NOT NULL, `place_occupe` int(11) NOT NULL, `statue` varchar(30) NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7; Et quelques entrées de test : INSERT INTO `batiment` (`id`, `id_region`, `id_territoire`, `type_zone`, `nom`, `etat`, `place_occupe`, `statue`) VALUES (1, 1, 1, 'plaine', 'champ', 'neuf', 2, 'actif'),(2, 1, 1, 'plaine', 'moulin', 'neuf', 1, 'inactif'),(3, 1, 1, 'plaine', 'moulin', 'abime', 1, 'actif'),(4, 1, 1, 'plaine', 'moulin', 'detruit', 0, 'inactif'),(5, 1, 1, 'plaine', 'champ', 'abime', 1, 'actif'),(6, 1, 1, 'plaine', 'champ', 'detruit', 0, 'inactif'); Alors voilà, si vous connaissez une méthode plus optimisé afin d'alléger la requête, je vous remercie de bien vouloir la partager Modifié 31 Juillet 2007 par fingolfin
fingolfin Posté 31 Juillet 2007 Auteur Posté 31 Juillet 2007 (modifié) Bon bah, j'ai trouvé une autre solution qui n'a plus rien à voir avec cette histoire, j'ai refait ma Base De Donnée ce qui me permet maintenant d'avoir juste une requête avec des jointures pour sélectionner toutes les informations nécessaires à l'affichage des productions, bon c'est une belle requête qui ne doit pas être légère à exécuter, mais sachant qu'il n'y en aura donc qu'une sur la page (en dehors des menus) je pense que c'est pas mal quand même, voici à quoi elle ressemble : $productions = mysql_query("SELECT production.production, production.etat AS etat_production, transport.nombre_char, transport.quantite AS transport_quantite, transport.type_ressource, donnees_batiment.capacite, donnees_batiment.quantite, batiment.place_occupe, batiment.etat, batiment.nom, batiment.stock FROM production LEFT JOIN transport ON production.id_region = transport.region_dep AND production.id_territoire = transport.territoire_dep AND production.type_zone = transport.type_zone AND production.production = transport.type_ressource LEFT JOIN batiment ON transport.region_dep = batiment.id_region AND transport.territoire_dep = batiment.id_territoire AND transport.type_zone = batiment.type_zone LEFT JOIN donnees_batiment ON batiment.type_zone = donnees_batiment.type_zone AND batiment.nom = donnees_batiment.nom WHERE production.type_zone = 'plaine'")or die(mysql_error()); Modifié 31 Juillet 2007 par fingolfin
smile Posté 31 Juillet 2007 Posté 31 Juillet 2007 Les requètes avec jointure, perso j'evite si ce sont des tables à milliers d'enregistrements. Je préfère 3 requètes simples exéctutées par pages qu'une énorme, cela évite de bouffer trop de ressources cpu mais c'est que mon avis
fingolfin Posté 1 Août 2007 Auteur Posté 1 Août 2007 (modifié) Oui, cette requête c'était pour tester, elle est très lourde et peut être divisé en deux requêtes avec jointures dont une qui ne lit que X entrées (X = nombre de ressources existantes et exploitées par le joueur) et l'autre qui donc lit seulement toutes les entrées des bâtiments du joueur dans la zone, alors qu'avant pour chaque bâtiment sélectionné je sélectionnai aussi les informations fixes concernant l'exploitation (active / inactive / nombre de charrettes de transport / production demandé par le joueur ...), en gros, voici à quoi ressemble mes requêtes dorénavant : $donnees_fixe = mysql_query("SELECT production.production, production.prod_demande, production.etat, transport.nombre_char, transport.quantite FROM production LEFT JOIN transport ON production.id_region = transport.region_dep AND production.id_territoire = transport.territoire_dep AND production.type_zone = transport.type_zone AND production.production = transport.type_ressource WHERE production.type_zone = 'plaine' AND production.id_region = '" . $_SESSION['region'] . "' AND production.id_territoire = '" . $_SESSION['territoire'] . "' AND transport.type_zone = 'plaine' AND transport.region_dep = '" . $_SESSION['region'] . "' AND transport.territoire_dep = '" . $_SESSION['territoire'] . "'")or die(mysql_error());/* On fait une seconde requête qui permettra de compter les stock et les productions */$productions = mysql_query("SELECT donnees_batiment.capacite, donnees_batiment.quantite, batiment.place_occupe, batiment.etat, batiment.nom, batiment.stock, donnees_batiment.production AS batiment_produit FROM batiment LEFT JOIN donnees_batiment ON batiment.type_zone = donnees_batiment.type_zone AND batiment.nom = donnees_batiment.nom WHERE batiment.type_zone = 'plaine' AND batiment.id_region = '" . $_SESSION['region'] . "' AND batiment.id_territoire = '" . $_SESSION['territoire'] . "'")or die(mysql_error()); Modifié 1 Août 2007 par fingolfin
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant