Page 1 sur 2

Optimisation de code

Posté : 12 févr. 2008, 14:59
par airaam
salut :)
alors je poste pas parce que mon code ne marche pas, mais parce que je le trouve pas optimisé

je suis donc curieux de voir comment des "bons" en php ferait en sorte que ce script s'execute en moins de ligne, si toute fois c'est possible :)

(désolé si le nombre de ligne maximum est dépassé)
<?php
$req = "SELECT * FROM matchs WHERE `airaam` = 1";
$resultat = mysql_query ($req, $connexion);
$airaam = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `yo` = 1";
$resultat = mysql_query ($req, $connexion);
$yo = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `patanch` = 1";
$resultat = mysql_query ($req, $connexion);
$patanch = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `badday` = 1";
$resultat = mysql_query ($req, $connexion);
$badday = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `yeto` = 1";
$resultat = mysql_query ($req, $connexion);
$yeto = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `jey` = 1";
$resultat = mysql_query ($req, $connexion);
$jey = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `yannick` = 1";
$resultat = mysql_query ($req, $connexion);
$yannick = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `isy` = 1";
$resultat = mysql_query ($req, $connexion);
$isy = mysql_num_rows($resultat);

$req = "SELECT * FROM matchs WHERE `zaza` = 1";
$resultat = mysql_query ($req, $connexion);
$zaza = mysql_num_rows($resultat);


$nom[1] = "zAZa";
$nom[2] = "Isy";
$nom[3] = "Yannick";
$nom[4] = "Airaam";
$nom[5] = "Yeto";
$nom[6] = "Jey";
$nom[7] = "Patanch";
$nom[8] = "Yo";
$nom[9] = "badday";

$num[1] = "$zaza";
$num[2] = "$isy";
$num[3] = "$yannick";
$num[4] = "$airaam";
$num[5] = "$yeto";
$num[6] = "$jey";
$num[7] = "$patanch";
$num[8] = "$yo";
$num[9] = "$badday";

array_multisort($num, SORT_DESC, SORT_NUMERIC,$nom, SORT_STRING);
echo "$nom[0] : $num[0]</br>";
echo "$nom[1] : $num[1]</br>";
echo "$nom[2] : $num[2]</br>";
echo "$nom[3] : $num[3]</br>";
echo "$nom[4] : $num[4]</br>";
echo "$nom[5] : $num[5]</br>";
echo "$nom[6] : $num[6]</br>";
echo "$nom[7] : $num[7]</br>";
echo "$nom[8] : $num[8]</br>";

 ?>
voilà merci de vos futures réponses, histoire que je continue à progresser :)

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

Posté : 12 févr. 2008, 15:08
par d0m
Déjà au départ il semblerait au premier coup d'œil que ta table matchs est mal conçue...

On va pas te l'optimiser mais t'expliquer comment faire.

Déjà pour tes requêtes tu as plusieurs fois la même, juste le champ dans la clause WHERE qui change.
Qui dit répétition dit boucle et tableau.

Tu peux déjà commencer par mettre tous les noms pour tes requêtes dans un tableau $noms par exemple.
Tu déclares un autre tableau $matchs qui contiendra tes valeurs que tu mettais dans tes variables $airaam, $yo,....

Ensuite tu parcours le tableau $noms, tu fais les requêtes dans la boucle et tu mets le résultat dans le tableau $matchs avec comme clé le nom.

Mais en refaisant ta table je pense que tu pourrais faire une seule requête bien plus pratique.

Décris nous ce que tu veux faire précisément?

Posté : 12 févr. 2008, 15:16
par Sedril
<?php
$nom = array("zAZa","Isy","Yannick","Airaam","Yeto","Jey","Patanch","Yo","badday");

foreach($nom as $k=>$n) {
	$req = "SELECT * FROM matchs WHERE `{$n}` = 1";
	$resultat = mysql_query ($req, $connexion);
	$num[$k] = mysql_num_rows($resultat);
}


array_multisort($num, SORT_DESC, SORT_NUMERIC, $nom, SORT_STRING);

foreach($nom as $k=>$n) {
	echo "{$n} ... {$num[$k]}<br>";
}
?>
On aurait pu l'optimiser comme ça ton code. Mais c'est vrai que ta BDD est bizarre. Si c'est important les minuscules pour le nom dans la requête, alors il faut utiliser lowercase().

Posté : 12 févr. 2008, 15:17
par zeus
Effectivement, ta table est mal concue puisque chaque colonne représente une données.

Il vaudrait mieux une colonne (disons "categorie") qui contiendrais airaam, yo, patanch, ... en tant que valeur.

Du coup, tu pourrais utiliser une requête du genre

Code : Tout sélectionner

SELECT categorie, COUNT(1) FROM match GROUP BY categorie
Cette requête te retourne le nombre d'enregistrement correspondants à chaque catégorie.

En plus d'optimiser le fonctionnement, l'amélioration que nous te donnons permettre l'évolutivité de ton code puisque l'ajout d'une nouvelle catégorie ne demandera pas de modification du code source ;)

Posté : 12 févr. 2008, 15:26
par airaam
re
ca c'est du rapide au niveau de la réponse ! :)

alors déjà ton principe de tableau et de faire une boucle sur la requête ça m'intéresse pas mal, si tu pouvais détailler un peu en prenant un exemple concret

ensuite pour la table je suis certain que mes tables manquent surement de logique :(

en fait quand je rentre un match sur le site j'indique le nom des joueurs ayant participé au match
j'ai donc un formulaire avec des cases à cocher ou non

airaam []
yo []
patanch []

et la je fait brut de pomme, c'est à dire j'appelle la case à cocher airaam "case_airaam" et si elle est cochée la valeur est 1 sinon 0
donc dans la table il y'a un champ qui s'appelle "case_airaam" et j'y insère une valeur 1 ou 0

et ca se passe comme ca pour les 9 joueurs de l'équipe.....
je me doute bien qu'il doit y avoir quelque chose de plus efficace mais en farfouillant sur le web j'ai rien trouvé de très clair

voila un screen de ma table

Image

EDIT : Alors en finissant mon post je viens de voir 2 réponses entre temps :)

merci sedril, c'est exactement ça que j'imaginai en parlant d'optimisation :)

pour cette fonction
foreach($nom as $k=>$n) {
    $req = "SELECT * FROM matchs WHERE `{$n}` = 1";
    $resultat = mysql_query ($req, $connexion);
    $num[$k] = mysql_num_rows($resultat);
}
ca veut dire que pour chaque entrée du tableau, il va faire la requête en incrémentant la valeur et il réinsère dans le tableau $num, c'est bien ca?


pour zeus : la j'avoue que j'ai du mal à te suivre :oops:
si tu pouvais détailler un chouille :)

Posté : 12 févr. 2008, 15:33
par zeus
Effectivement, il y a un énorme problème de conception.

Pour marquer quels joueurs ont participés à quels matchs, il te faut 3 tables :
Une table "match" qui ne contient que les données du matchs (adversaire, score, ...)
Une table "joueur" qui contient les données des différents joueurs (id, pseudo)
Une table "participe" qui contient l'association entre un match et un joueur.

Sinon, le principe du tableau donnera un code moins long en nombre de caractères, mais pas plus optimisé puisque tu feras autant de requête, autant de récupération, ...

Posté : 12 févr. 2008, 15:34
par Sedril
Le code, c'est une chose, la structure de la bdd une autre. Tout dans ton programme repose sur une seule table :( C'est pas bon, il faut essayer de regrouper les informations sur plusieurs entités.

Par exemple :

joueur (id_joueur, pseudo, email)
equipe (id_equipe, nom)
map (id_map, nom)
partie (id_joueur, id_equipe, id_map, date, score)

On reviendra sur la partie code plus tard. Essaye d'adapter ta BDD ou alors expose les informations de ta table avec leurs significations. On peut t'aider à rassembler les infos et trouver les entités.

Posté : 12 févr. 2008, 15:36
par iclo
Je crois qu'il faut se poser les "bonnes questions":
Que se passera-il si un jour il y a beaucoup plus de joueurs qu'actuellement ?
Comment faire en sorte de pouvoir ajouter un nouveau joueur, sans devoir modifier la structure de la base de donnée, et le code de l'application ?
A partir du moment où la base de donnée possède une bonne structure, on ne rencontre pas de grosses difficultés à programmer un code efficace.

Posté : 12 févr. 2008, 15:47
par airaam
oula j'ai pas l'habitude que ca réponde aussi vite sur un forum :)

jvai essayer de résumer vos remarques

en gros vous me dites qu'il faudrait faire

table match
id_match
adversaire
score
map1
map2
screen1
screen2
screen3
screen4
date

table joueur
id_joueur
pseudo


je vois l'interet de séparer les deux tables, effectivement si un nouveau joueur rentre dans l'equipe (ce qui ne sera pas le cas, mais parlons concret :) ), pas besoin d'ajouter un nouveau champ

le coup de la table "participe" je comprend à peu près son intérêt mais je vois pas trop comment la faire intervenir

je pense que le formulaire me permet de rentrer toutes les infos nécessaire à table match, dans le formulaire je récupère dynamiquement le contenu de table joueur et c'est table participe qui va contenir les noms de ceux qui ont fait le match?

on aurait donc une table participe
id_participe
id_match
id_joueur

mais le champs id_joueur va contenir plusieurs entrées, faudra donc que j'insère un ";" (par ex) pour pouvoir séparer les valeurs ?

ai je capter la logique ?
et le plus important, avez vous capté la mienne ? :D

Posté : 12 févr. 2008, 15:50
par Sedril
la table participe ressemblerait plutot à cela :

id_match
id_joueur

ce qui donne avec un cas concret pour : match 1, joueurs 2, 5 et 7

on insère dans la table participe

1,2
1,5
1,7

Comme cela on peut trouver les joueurs qui ont participé au match 1 avec la requête :

Code : Tout sélectionner

SELECT id_joueur FROM participe WHERE id_match = 1

Posté : 12 févr. 2008, 16:03
par airaam
ah ben oui...que chui con...

donc je commence à cerner la modification que je dois apporter à mes tables

si je dois faire une requète pour calculer le nombre de fois où j'ai fai un match par exemple
et que je suis le joueur avec l'id 1

la requète sera du genre

SELECT count(*) FROM participe WHERE id_joueur = 1

et la pour eviter de retomber dans la succession de requete je refait le code optimiser avec le foreach?

Posté : 12 févr. 2008, 16:04
par iclo
Et tout aussi simplement compter le nombre de match auxquels chaque joueur à participé, avec une seule requête ;)

Posté : 12 févr. 2008, 16:09
par Sedril
et la pour eviter de retomber dans la succession de requete je refait le code optimiser avec le foreach?
Tu fais une requête du genre :

Code : Tout sélectionner

SELECT count(*), id_joueur FROM participe GROUP BY id_joueur
Ca ramènera 1 ligne par joueur et te donnera le nombre de participation à un match. Il faudra parcourir les enregistrements ramenés par la requête.

Posté : 12 févr. 2008, 16:10
par airaam
oui mais alors la je suis perdu des étapes à suivre au niveau du code :?

il faut recuperer les pseudos des joueurs et les id_joueurs
les mettre dans deux tableaux
faire un foreach comme indiqué ci-dessus

j'ai bon??[/php]

Posté : 12 févr. 2008, 16:13
par Sedril
Non, le code n'est plus adapté à la structure de la BDD maintenant, il faut réécrire. La requête ci-dessus ramènera N lignes à parcourir. Elles contiendront tous les joueurs ainsi que leur nombre de participation à un match.

Tu n'as donc pas besoin de préciser les noms des joueurs.