Aller au contenu

Sujets conseillés

Posté (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 :smartass:

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é par fingolfin
Posté (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é par fingolfin
Posté

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 :)

Posté (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é par fingolfin

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...