JeuWeb - Crée ton jeu par navigateur
[Résolu] Performances dans une boucle avec Update - 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 : [Résolu] Performances dans une boucle avec Update (/showthread.php?tid=333)

Pages : 1 2


[Résolu] Performances dans une boucle avec Update - zeppelin - 31-03-2008

Bonjour tout le monde!

J'ai un jeu en php mysql qui fonctionne au tour par tour. Toutes les 30min je mets donc à jour toutes les ressources de chaque joueur dans des boucles. Le problème réside dans la boucle qui mets à jour le mana. Chaque joueur possède un héros, chaque niveau de héros incrémente de 1 le mana reçus par tour. Le mana et le niveau du héros ne sont pas dans la même table, mais le problème ne dois pas être la (4,6 secondes pour uniquement le select et echo ligne par ligne)... A part contre si je change l'echo avec le vrai update, tout devient trop lent (104 secondes pour updater le mana de 4600 joueurs).

Voici ma boucle:

$request = 'SELECT ress.uid, ress.mana, hero.niveau FROM ress, hero where ress.uid = hero.uid';
$request2 = mysql_query($request);
while($infos = mysql_fetch_assoc($request2)) {
$NewMana = $infos['mana'] + $infos['niveau'];
mysql_query('UPDATE ress SET mana='.$NewMana.' WHERE uid='.$infos['uid']);
}

Y a t'il un moyen d'améliorer cette boucle et la rendre plus rapide?? Un grand merci d'avance, zepp'


RE: poblème de rapidité dans une grande boucle avec update - pascal - 31-03-2008

salut,

tu peux tout mettre à jour en une seule requête UPDATE, avec une jointure :
http://dev.mysql.com/doc/refman/5.0/fr/update.html

ça sera sûrement plus rapide que faire 1 + 4600 requêtes.

A+

Pascal


RE: poblème de rapidité dans une grande boucle avec update - zeppelin - 31-03-2008

*tu as encore beaucoup à apprendre, jeune padawan*! :heuuu:

Ok merci beaucoup pascal, je vais me pencher la dessus, au pire je reviens solliciter ton aide, je n'ai encore jamais utilisé des join dans les update Smile


RE: poblème de rapidité dans une grande boucle avec update - pascal - 31-03-2008

ok Smile

utilises une base de test au début Wink

A+

Pascal


RE: poblème de rapidité dans une grande boucle avec update - Byleth - 31-03-2008

Oh tu sais, on a toujours à apprendre : merci pascal pour cette info dont je n'avais jamais eu besoin mais qui peut se réveler fort utile :p


RE: poblème de rapidité dans une grande boucle avec update - zeppelin - 31-03-2008

Enfaite je suis un peu perdu je dois t'avouer, je ne vois pas bien par ou attaquer... J'ai éssayé plusieurs options, mais aucune ne donne le résultat voulu...

dernier test:

mysql_query('UPDATE ress2 SET mana = (ress2.mana + hero2.niveau) WHERE ress2.uid = hero2.uid');

Apparament ça ne fonctionne pas comme ça non plus... Mais je suis sur le bon chemin ou complètement à côté de la plaque? ^^

ps. les 2 au tables c'est ma table test que j'ai cloner de l'original!


RE: poblème de rapidité dans une grande boucle avec update - pascal - 31-03-2008

une astuce pour faire un UPDATE multi tables :
faire un SELECT avant, avec les jointures et les nouvelles valeurs à avoir :
Code :
SELECT ress.mana + hero.niveau
FROM  ress, hero
WHERE  ress.uid = hero.uid;

on valide le résultat en exécutant la requête.

ensuite on transcrit en UPDATE:
Code :
UPDATE ress, hero
SET ress.mana = ress.mana + hero.niveau
WHERE  ress.uid = hero.uid;

à utiliser sur les tables test.

A+

Pascal


RE: poblème de rapidité dans une grande boucle avec update - zeppelin - 31-03-2008

Bon la variante suivant fonctionne, mais prends encore 50 secondes...

Code PHP :
<?php 
mysql_query
('
UPDATE ress2
LEFT JOIN hero2 on ress2.uid = hero2.uid
SET ress2.mana = ress2.mana + hero2.niveau
'
);

pareil pour ton code, 50 secondes aussi

Code PHP :
<?php 
mysql_query
('
UPDATE ress2, hero2
SET ress2.mana = ress2.mana + hero2.niveau
WHERE ress2.uid = hero2.uid
'
);

C'est déjà la 3ème variante qui fonctionne mais qui bouffe toujours encore beaucoup de ressources serveur.

pascal, dans ta grande bonté et ton envie de partager ton grand savoir sur MYSQL, aurais tu un un code plus optimisé? Ou comment aurais tu écris la requête toi?

Un grand merci, je pense que se sujet va aider plus d'une personne sur les updates Wink


RE: poblème de rapidité dans une grande boucle avec update - Roworll - 31-03-2008

Quelques petites questions en vrac pour tenter d'y voir plus clair:
Combien de lignes as-tu dans chaque table ?
Les index sont-ils bien positionnés ?
As-tu essayé d'utiliser l'instruction EXPLAIN pour voir comment le moteur MySQL appréhende la requête ?


RE: poblème de rapidité dans une grande boucle avec update - phenix - 31-03-2008

Le mieux ne serait'il pas de mettre a jour le Mana a la connection du joueur ?

Sinon, si tu doit vraiment mettre tout à jour, comme la dit Roworll, positionne tes index correctement, met des clée primaires et prie pour que sa marche :p