Des centaines de SELECT d'un coup (pas d'aide, juste un conseil)

CG
Invité n'ayant pas de compte PHPfrance

30 août 2008, 00:25

Bonjour la communauté,

J'ai cherché longuement une réponse à mon interrogation, sur votre forum, mais aussi sur Google, sans succès. Il faut dire que ma demande est très spécifique (pour ne pas dire tordue !). Il ne s'agit pas d'une demande d'aide précise, mais d'un simple conseil. J'espère poster dans le bon forum, mais je n'en ai pas trouvé de plus adéquat. Aussi vais-je essayer de vous l'expliquer le plus simplement possible :

Je créé actuellement un jeu PHP. Vous allez dire "Encore un qui bidouille PHP et qui a la prétention de s'attaquer à un jeu web", mais moi j'y travaille depuis 2 ans, à mes heures perdues, en plus de mon métier de webmaster (j'ai plusieurs portails PHP à mon actif, réalisés par moi-même ligne par ligne). Il s'agit d'un jeu type "jeu de plateau". L'espace de jeu contient environ 800 "cases".

Chaque case fait appel à la base de données. Selon l'information écrite dans la BDD, chaque "case" contient un élément spécifique. Pour récupérer les informations de chaque cas je dois donc faire un SELECT (logique). Ma question est donc très simple : mon serveur (dédié) pourra-t-il supporter l'exécution de 800 SELECT d'un coup (au chargement de la page) en sachant que plusieurs dizaines de joueurs pourront être sur la page en même temps. Je me pose simplement la question de savoir si un serveur peut "techniquement" supporter plusieurs centaines de SELECT simultés. En sachant qu'il ne s'agit que de SELECT (pas de UPDATE ni de DELETE par exemple).

Ma BDD contient 800 lignes prédéfinies (une ligne pour chaque "case" donc).

Voici un shéma type d'un SELECT :
<?php
$sql="SELECT * FROM matable WHERE id_case='8'"; // la case n°8 par exemple
$query=mysql_query($sql);
$data_case=mysql_fetch_array($query);
?>
Si cela peut vous aider à m'apporter une réponse, l'OS de mon serveur est un Linux RedHat 7.2.


Merci à ceux qui éclairciront ma lanterne :wink:

ViPHP
ViPHP | 5924 Messages

30 août 2008, 01:15

:shock:
T'es un psychopathe toi…

Tu ne pourrais pas tout faire en une seule requête ? Au pire utilise des procédures stockées…

CG
Invité n'ayant pas de compte PHPfrance

30 août 2008, 02:54

Merci de me guider. Mais dans mon bout de code que j'ai mis dans mon message précédent, je n'arrive pas à comprendre comment je pourrais faire un seul SELECT pour mes 800 cases. En sachant que dans la BDD, une ligne correspond à une case (donc 800 lignes).

J'avais pensé aux procédures stockées mais j'espérais qu'il y aurait une solution plus simple. Mais si c'est la seule...

CG
Invité n'ayant pas de compte PHPfrance

30 août 2008, 05:38

J'ai cherché sans succès. Je bloque. Pour le dire plus simplement, voilà mon code :

Dans mon jeu web, exemple de 2 cases :
<?php
// Case n°01
$sql="SELECT case_id, case_nom FROM table_cases WHERE case_id='01'";
$query=mysql_query($sql);
$data_case=mysql_fetch_array($query);

echo "<div id=\"01\">".$data_case['case_nom']."</div>";

// Case n°02
$sql="SELECT case_id, case_nom FROM table_cases WHERE case_id='02'";
$query=mysql_query($sql);
$data_case=mysql_fetch_array($query);

echo "<div id=\"02\">".$data_case['case_nom']."</div>";

// ect..... jusqu'à 800 cases !
?>
...je me doutais bien que cette manière est "psychopathe", pour reprendre vos termes, Sékiltoyai. Mais dans ce cas, comment je peux récupérer mes 800 lignes avec une seule requête SELECT ? J'ai bien-sûr pensé à faire un SELECT sans clause WHERE (dans ce cas les 800 lignes sont récupérées), mais comme vous pouvez le voir dans mon code ci-dessus, mon plateau de jeu est fait en CSS est chaque case est imbriquée dans une balise DIV (l'ID de la DIV doit correspondre à l'ID de la ligne dans la BDD). C'est pour ça que jusque là, la seule solution que j'ai trouvée c'est 800 SELECT ! (SELECT..... WHERE ID de la case) :? Je suis persuadé que je peux me passer des procédures stockées dans ce cas précis.


Merci de votre aide.

ViPHP
ViPHP | 928 Messages

30 août 2008, 05:49

Bonsoir à toi,
soit je suis complètement à l'ouest, soit ta question est très simple (à tel point que je trouve ettonant que tu la poses avec ton expérience de 2 ans de PHP et de plusieurs sites codés de A à Z).

Ce qui est choquant c'est que tu parts du principe que ton design (côté client) est limitant pour ce qui va se passer côté serveur (en l'occurrence la récupération des requêtes) ... alors que le principe c'est que c'est ton script PHP qui te génère ton HTML, pas l'inverse ! Il n'y a donc aucune restriction, et c'est absurde de vouloir faire requête à cause d'un design.

Rien ne t'empèche de récupérer tous les résultats en ... 1 seule requête. Il suffit de faire une boucle sur tes résultats :
$sql="SELECT case_id, case_nom FROM table_cases";
$query=mysql_query($sql) OR die(mysql_error()); // Toujours vérifier ses retours de requête SQL, règle de base dans le développement web !

$i = 0;
while ($data_case=mysql_fetch_array($query))
{
   echo "<div id=\"" + $i + "\">".$data_case['case_nom']."</div>";
   $i++;
}
mysql_free_result($query);
Et hop je te génère toutes tes cases de tableau en 10 lignes ^^

CG
Invité n'ayant pas de compte PHPfrance

30 août 2008, 06:50

Bonjour Genova,

Merci de ton aide. Rassure-toi, j'utilise au maximum PHP pour générer mon code HTML :wink: Ceci dit, ton exemple était très pertinent : c'est de ma faute, j'ai oublié de préciser un détail qui semble visiblement important dans mon explication. En fait, mes DIV correspondent à des "cases" d'un plateau de jeu (prenons pour exemple le plateau du Monopoly). Et du coup, mes DIV ont chacunes des coordonnées bien précises (letf et top) :
<div id=06 name=06 style='position: absolute; left: 158px; top: 194px;'><?php echo $data_case["case_nom"]; ?></div>

C'est pour cela que jusque là, la seule solution trouvée était un SELECT.....WHERE case_id='NUMERO_DE_LA_DIV' avec mysql_fetch_array avant chaque DIV. Mais voilà, j'ai 800 cases sur la même page, et Sékiltoyai a confirmé ma crainte : c'est du suicide pour le serveur.

N'y a-t-il pas moyen de faire un seul SELECT pour toutes mes cases ?

PS : le code présenté ici est simplifié, en vérité il est un peu plus complexe (jointures notamment) mais j'ai préféré vous omettre ces détails pour ne pas compliquer mon explication qui est déjà bien laborieuse ! :lol:


Merci encore à tous, notamment de vos réponses rapides :wink:

ViPHP
ViPHP | 4039 Messages

30 août 2008, 10:25

Hmm.. un bonne pratique serait d'exécuter ce qui doit l'être avant de commencer à sortir le code html.. c'est beaucoup plus flexible..

Pour ce qui est des cases, moi je pense simplement à un IN..

Code : Tout sélectionner

select * from truc where id_case in ('01','02','03','04)
puis une boucle..

Code : Tout sélectionner

foreach $case from $resultat $html =sprintf('<div id="%d">%s</div>',$case[id],$case[contenu]);

quelque chose du style.. (non, c'est pas du bon code, c'est juste pour présenter le principe)
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

ViPHP
ViPHP | 5924 Messages

30 août 2008, 10:48

Non non non. Genova a raison. Il y a 800 cases dans la base, on récupère les 800 cases, on ne se fait pas chier avec un WHERE inutile et coûteux :

Code : Tout sélectionner

SELECT * FROM truc;
tout simplement.

Je ne vois même pas comment expliquer vu que c'est une pratique de base de PHP+MySQL.

Bref, en quoi est ce différent de faire un

Code : Tout sélectionner

SELECT * FROM truc WHERE case='$id';
que de récupérer $cases[$id] dans un tableau de cases ?

Il te suffit juste de stocker les résultats de ta requête dans un tableau, je le redis c'est la base de PHP/MySQL, manifestement tu devrais trainer un peu sur les le site du zero ou des sites du genre parce que sinon tu vas dans le mur…

Eléphant du PHP | 217 Messages

30 août 2008, 10:50

Je suis d'accord avec la solution de Genova.

Si le plateau de jeux est basique (rectangle ou carré) tes cases peuvent se placer automatiquement avec un style css sans avoir recours a de la position absolu.
Si ce n'est pas le cas alors mets en place les position top et left des cases en base de données pour les affecter dans la boucle qui parcourra les résultats du select.

ViPHP
ViPHP | 4039 Messages

30 août 2008, 15:42

Non non non. Genova a raison. Il y a 800 cases dans la base, on récupère les 800 cases, on ne se fait pas chier avec un WHERE inutile et coûteux :

Code : Tout sélectionner

SELECT * FROM truc;
tout simplement.
Ah, au temps pour moi, j'avais zappé le truc comme quoi il fallait tout le plateau (et non seulement une partie). Alors je rejoins sékil, tu sélectionne le tout en une fois, et basta.

Sinon, un tableau ne serait pas plus adapté à un plateau de jeu (pour peu que les cases soient rectangulaires), plutôt que des divs ? y'a pas as s'amuser à les placer..
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

ViPHP
ViPHP | 5924 Messages

30 août 2008, 16:10

C'est pas faux :)
Quand on dit les tableaux c'est pas valide XHTML, c'est quand ils sont utilisés à mauvais escient…

Eléphanteau du PHP | 25 Messages

30 août 2008, 18:21

Bonjour à tous,

Merci de vos réponses nombreuses. J'ai fait de nouvelles manip' aujourd'hui selon vos suggestions.


Sékiltoyai :arrow: ta suggestion est juste, ceci dit, j'avais déjà fait ce test avant de vous solliciter, mais le résultat retourné était vide. Comme dit dans mon post précédent, en réalité le code est un peu plus complexe (jointure), alors voilà le code exact :
$sql_lot = "SELECT lot_id, lot_bat, bat_id, bat_img 
FROM lots
GROUP BY lot_id
LEFT JOIN bats
ON bat_id = lot_bat"
// WHERE lot_id='NUMERO_DE_LA_DIV';
Avec le WHERE, ça marche, à condition de renseigner les 800 SELECT...... WHERE....... :shock:
Sans le WHERE ça retourne un champ vide. J'ai même essayé avec un 'GROUP BY lot_id', sans succès.


D'après toutes les suggestions que vous m'avez données, celle de mojorisin m'apparait comme celle qui se rapproche le plus que je recherche : c'est vrai je n'ai pas pensé à renseigné tout simplement les coordonnées left et top dans la base de données.


Merci encore à tous, je vous remercie par avance si vous pouvez encore m'aider dans ma démarche (la suggestion de mojorisin me parait la plus proche, mais n'y a-t-il pas malgré tout une autre solution ?) :wink:

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]

Eléphanteau du PHP | 25 Messages

30 août 2008, 18:25

Veuillez m'excuser, je n'avais pas vu le post de Berzemus. Pour répondre à ta question, le plateau est sous forme de 3D isométrique (type jeux de gestion) et il y a plusieurs calques les uns sur les autres. Voilà pourquoi je pense ne pas pouvoir utiliser un simple tableau.

Je n'ai pas "osé" vous donné l'adresse de mon projet (je tiens un blog relatif au développement), mais si vous le souhaitez, je peux vous donner le lien du blog sur ce topic ? Techniquement cela ne vous apportera rien de plus, si ce n'est que vous verrez exactement de quoi il s'agit exactement :wink:

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]

ViPHP
ViPHP | 5924 Messages

30 août 2008, 18:55

Ta clause JOIN est mal placée, elle se met après la clause FROM…
Par ailleurs, je te suggère de débugguer quand tes requêtes ne fonctionnent pas : http://www.phpfrance.com/forums/voir_sujet-19378.php

Si une requête ne fonctionne pas, cela ne veut pas dire que la méthode est mauvaise, cela veut dire que la requête est mauvaise…

Eléphanteau du PHP | 25 Messages

30 août 2008, 19:35

Ta clause JOIN est mal placée, elle se met après la clause FROM…
Par ailleurs, je te suggère de débugguer quand tes requêtes ne fonctionnent pas : http://www.phpfrance.com/forums/voir_sujet-19378.php

Si une requête ne fonctionne pas, cela ne veut pas dire que la méthode est mauvaise, cela veut dire que la requête est mauvaise…
Excuse-moi j'ai du louper quelque chose, ma clause JOIN est bien après la clause FROM pourtant ? Tu voulais plutôt dire qu'elle se met après la clause WHERE, peut-être ?

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]