Forum TourDeJeu · Règles du forum | Aide Recherche Membres |
Bienvenue invité ( Connexion | Inscription ) | Recevoir à nouveau l'email de validation |
la_couenne |
Ecrit le : Mardi 16 Avril 2013 à 19h16
|
Newbie Groupe : Membre Messages : 9 |
Bonjour à tous!
Voilà, cela fait + d'un an que je suis sur le développement de mon jeu web, ça commence à donner quelque chose de pas trop mal. Seulement avant avec une trentaine de joueurs sur ma petite carte, ma page s'affichait en 2 secondes, maintenant j'ai agrandi la carte de jeu et du coup avec un seul perso dessus, elle met jusqu'à 5 sec pour s'afficher! je vais devoir sérieusement apprendre à optimiser mes bases de données.. Voici mon problème, j'ai 100 cartes, qui contiennent chaqune 40x40 cases. J'affiche une carte à la fois, celle ou se trouve le joueur. Ma table s'appelle "world" et a 4 colonnes (je simplifie un peu, mais le principe est là..) ------------------------------------------ | world | ------------------------------------------ | carte | case | contenu | id_joueur | 100 | 1010 | ici il y a le contenu la case 1010 de la carte 100 | 100 | 1110 | et là le contenu la case 1110 toujours sur la carte 100 ... | 101 | 1010 | ici c'est une autre carte (la 101) donc "case" ne peut pas être primaire puisque 1010 existe dans la carte 100.. Ma question est: comment indexer si je n'ai pas de clé primaire? (des contenus pas unique puisque les cases 1010 seront sur plusieurs carte) est-ce que KEY `carte` (`carte`,`case`); est correct? J'ai donc créé donc mon index, seulement maintenant j'ai un problème d'affichage des cases: elles n'apparaissent plus dans l'ordre: Avant avec ma table sans index et en exécutant ma requête: SELECT `case` FROM `world` WHERE `carte`='100' il me retournait: 1010 1110 (soit les coordonnées de ma case X:11 et Y:10) 1210 1310 1410 ... et maintenant que j'indexe ma table en ajoutant: KEY `cluster` (`cluster`,`case`) lors de sa création ma requête: SELECT `case` FROM `world` WHERE `carte`='100' me retourne: 1010 1011 (soit les coordonnées de ma case X:10 et Y:11) 1012 1013 1014 ... seulement c'est un énorme problème, car je suis obligé de faire apparaître mes cases dans le bon ordre, afin de les afficher par coordonnées X-Y! Donc ma carte de 40x40 cases se présente: 1010 1110 1210 1310 ... 1011 1111 1211 1311 ... 1012 1112 1212 1312 ... ... J'ai essayé de mettre: SELECT `case` FROM `world` WHERE `carte`='100' ORDER BY `case` ASC mais évidement c'est pas ça (ca m'affiche 1010 1011 ...) j'ai solutionné mon problème en faisant tout bêtement une boucle pour l'affichage de chaque ligne: $Y=10; debut: $reponse = mysql_query("SELECT `case` FROM `world` WHERE `carte`='100' AND `case` like '%".$Y."' ORDER BY `case` ASC"); //ça affiche toutes les cases pour $Y (donc par ligne) while ($donnees = mysql_fetch_array($reponse)){ echo $donnees['case'].'<br/>';} if ($Y<40){$Y++; goto debut;} Mais ca me fait pour afficher une carte: 40 requêtes pour mes 40 lignes Y, c'est pas le top de l'optimisation ça.. Donc si mon problème parle à quelqu'un, je serais très intéressé Bonne fin d'semaine à tous.. |
Cedric |
Ecrit le : Samedi 18 Mai 2013 à 01h56
|
Ouf Groupe : Membre Messages : 368 |
Je n'avais pas vu ton message... mais le probleme que tu as est que fondamentalement il te faudrait decomposer ton numero de case en 2.
1011 => X = 10 / Y = 11 Apres il te sera tres facile de tout ordonner. Je te conseille sinon : - de creer une clef primaire auto increment - de creer un index sur ton monde - de creer un index sur X - de creer un index sur Y ... vu comment tu comptes y acceder. -------------------- |
la_couenne |
Ecrit le : Mercredi 22 Mai 2013 à 10h27
|
Newbie Groupe : Membre Messages : 9 |
Merci bcp pour ta réponse!
J'avais bien pensé séparer en deux mes numéros de cases, mais à ce moment je dois changer tout mon code, et ca ne me tente vraiment pas! en tout cas pas pour le moment.. Ca fait 1 an que je suis sur le développement de mon jeu, pour le moment je le teste comme ca en local, ce qu'il y a c'est que pour le faire tourner mon serveur fait tourner un cron toute les 10 secondes, alors qu'une fois hébergé les crons on peut les faire se lancer au minimum 1x toutes les 15min.. Mon jeu est un peu "spécial", en fait les joueurs définissent le génome de petites bébêtes, qui vont s'adapter à leur environnement et se reproduire. Si le joueur veut conquérir un endroit précis du monde, ses bestioles devront savoir s'adapter à chaque partie du monde pour atteindre l'endroit visé.. Ca paraît compliqué dit comme ca, mais c'est intéressant comme jeu, mon problème c'est que ce n'est pas tellement les joueurs qui déclenchent des actions, c'est le serveur qui fait se déplacer leur bestioles, donc quand il y en a 100 ca marche, mais quand il y en a 1'000 il est obligé de les mettre à jour toutes les 10 ou 15 secondes Bref j'y travaille et on verra ce qu'il en ressort.. et une fois je pourrais aussi présenter l'idée de mon jeu voir ce que vous en dites, mais j'aimerais pas en parler pour abandonner 3 mois après... Merci encore pour ta réponse! A tout bientôt Ce message a été modifié par la_couenne le Mercredi 22 Mai 2013 à 10h29 |
Oelita |
Ecrit le : Mercredi 22 Mai 2013 à 11h58
|
Alien Groupe : Admin Messages : 1592 |
Evite les select LIKE de toutes façons, et encore moins 40 à la suite.
Fais un unique select de toutes les cases de ton monde, puis travaille sur le tableau des résultats (une boucle sur toutes lignes du tableau) pour ajouter les deux colonnes X et Y au tableau (ou en faire un autre), à partir du numéro de la case. Après, tu tries le tableau sur la colonne Y (fonction PHP) et c'est bon. Le travail sur le tableau en PHP prendra moins de temps que tes 40 requêtes avec LIKE. Après réflexion, tu peux aussi récupérer directement ta valeur Y dans ton select en faisant un calcul modulo 100 du numéro de la case (j'ai pas essayé mais ça devrait fonctionner ) : select case, MOD(case, 100) as Y, donnees FROM world WHERE carte=100 ORDER BY Y ASC, case ASC -------------------- |
la_couenne |
Ecrit le : Dimanche 26 Mai 2013 à 20h12
|
Newbie Groupe : Membre Messages : 9 |
Merci de ta réponse! j'ai pas répondu tout de suite car j'ai pas eu le temps de m'y pencher, mais ça me semble être une bonne idée, c'est vrai que je n'ai pas pensé travailler sur un tableau!
Dès que j'ai un peu de temps, je vais m'y repencher, comme pour l'instant je travaille en local j'ai pas de problème, mais je serais obligé d'y régler assez vite. Je te tiendrai au courant de ce que j'arrive à pondre |
Gwym |
Ecrit le : Mardi 28 Mai 2013 à 20h53
|
Kid Groupe : Membre Messages : 17 |
Une solution serait plutôt que de coder "case" en caractères (i.e. comme présenté, deux digits pour x deux digit pour y), mettre case en valeur numérique pure "numéro de la case" allant de 0 a 40*40
carte case 1 1 1 2 1 ... 1 1600 2 1 etc et récupérer les coordonnées select case, ... FROM world WHERE carte= n puis extraire au niveau du code (ou directement dans le sql) x = (int) (case / 40) y = case % 40 Par contre pourquoi ne pas simplement vraiment faire trois colonnes ? carte | x | y car au moindre changement de structure (exemple tu décides de faire des cartes de 50 par 30) il faudra faire des changements dans le code, alors qu'un SELECT x, y FROM world WHERE carte = n sera toujours valide |