Ma façon d'indexer est-elle correcte?

mailliam Messages postés 261 Date d'inscription mardi 2 juillet 2002 Statut Membre Dernière intervention 10 mars 2014 - 27 mars 2013 à 17:28
 nicotontige - 29 mars 2013 à 11:31
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 "world":
carte -- case -- contenu -- id_joueur
-------------------------------------
100 ---- 1010 ---- . . .
100 ---- 2020
101 ---- 1010
J'ai simplifié un peu, mais le principe est là..

Jusqu'à maintenant je n'avais qu'une carte, j'avais mis ma colone "case" en clé primaire, mais si j'ajoute des cartes, cette colone va avoir des doublons donc j'ai créé un index sur mes colonnes "carte" et "case" de cette façon:
KEY `carte` (`carte`,`case`);

Mais est-ce la bonne solution? et dois-je dois-je forcément mettre une clé primaire? (car pour ce faire je devrais ajouter une colonne sans doublons..)

Maintenant mes pages s'affichent + rapidement, mais mon problème c'est qu'avant j'affichais ma carte avec la requête:
SELECT `contenu`, `case` FROM `world` WHERE `carte`='100' ORDER BY `case` ASC
seulement maintenant il ne tient pas compte de ORDER BY `case` ASC et j'ai mes cases qui ne sont plus dans le bon ordre!

J'ai lu sinon dans l'aide qu'on peut créer un index de cette façon:
CREATE INDEX #nom_index
ON #nom_schem.#nom_table
(#colonne1 [ { ASC | DESC } ] [, #colonne2 [, ... #colonneN ]]] )
mais je ne comprend pas bien la différence et si cela serait intéressant dans mon cas.

Merci d'avance pour vos précieuses lumières

4 réponses

nicotontige
28 mars 2013 à 10:42
Bonjour,

Il est préférable de mettre des clés primaires effectivement.
Si j'ai bien compris le fonctionnement actuel, un joueur ne peut pas se trouver sur la même case qu'un autre joueur. C'est voulu j'espère

Je comprend pas pourquoi ta requête ne prend pas en compte le ORDER BY, il devrait pourtant ...
Est-ce que tu as une erreur qui est ressorti de ta requête ? Pour moi c'est la solution la plus simple.

J'espère que depuis que tu as rajouté des cartes, tu as aussi changé ta BDD ?
Car après tout ce que tu viens de dire, je vois 3 tables différentes :

------------
| CARTE |
------------
| id_carte |
| nom_carte|
------------

------------
| CASE |
------------
| id_case |
| id_carte |
| id_joueur|
| contenu |
------------

--------------
| JOUEUR |
--------------
| id_joueur |
| nom_joueur |
| ........ |
--------------

Et dans cette optique, la requête que tu nous as donné fonctionne. Et je confirme qu'il faut bien mettre au minimum 2 clés primaires (id_case, id_carte), sauf si tu offres la possibilité que plusieurs joueurs soit sur la même case, et là il te faudra 3 clés primaires (id_case, id_carte, id_joueur).
0
mailliam Messages postés 261 Date d'inscription mardi 2 juillet 2002 Statut Membre Dernière intervention 10 mars 2014 3
28 mars 2013 à 23:28
Tcho!

Pour commencer, merci de m'avoir répondu!

En fait oui j'ai plusieurs tables, mais celle que je cherche à indexer est bien une seule, qui s'appelle "world": (qui a 4 colonnes)
------------------------------------------
| world |
------------------------------------------
| carte | case | contenu | id_joueur
| 100 | 1010 | ici il y a ce que contient la case 1010 de la carte 100
| 100 | 1110 | ici il y a ce que contient la case 1110 de la carte 100
...
| 101 | 1010 | ici c'est une autre carte (la 101) donc "case" ne peut pas être primaire

ma question était: comment indexer si je n'ai pas de clé primaire? (des contenu pas unique puisque les cases 1010 seront sur plusieurs carte)
est-ce que KEY `carte` (`carte`,`case`); est correct?

Sinon j'ai trouvé l'origine de mon problème d'affichage des cases dans l'ordre:
en créant ma table sans index et en exécutant ma requête:
SELECT `case` FROM `world` WHERE `carte`='100'
il me retourne:
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:
1010 1110 1210 1310 ...
1011 1111 1211 1311 ...
1012 1112 1212 1312 ...
...

donc pour résumer ma question: comment je peux mettre ma requête:
SELECT `case` FROM `world` WHERE `carte`='100'
et avoir
1010
1110
car j'ai mis
SELECT `case` FROM `world` WHERE `carte`='100' ORDER BY `case` ASC mais évidement c'est pas ça (ca m'affiche 1010 1011 ...)

Je sais que c'est pas facile à comprendre, merci beaucoup en tout cas!
0
mailliam Messages postés 261 Date d'inscription mardi 2 juillet 2002 Statut Membre Dernière intervention 10 mars 2014 3
29 mars 2013 à 00:17
Re,

ne cherche plus j'ai solutionné mon problème en faisant tout bêtement:
$Y=10;
debut:
$reponse = mysql_query("SELECT `case` FROM `world` 
WHERE `carte`='100' AND `case` like '%".$Y."' ORDER BY `case` ASC");
while ($donnees = mysql_fetch_array($reponse)){
echo $donnees['case'].'
';
}
if ($Y<50){$Y++; goto debut;}


Par contre mon indexation KEY `carte` (`carte`,`case`); ne me fait rien gagner! je vais chercher pour modifier ma façon de faire, afin d'avoir une table avec des clés primaires uniques
Ca me semble être la seule façon..

Si tu as une autre idée, n'hésite pas
0
nicotontige
29 mars 2013 à 11:31
L'indexation ne fait sert pas en terme de "gain de temps", il te servira juste à éviter des erreurs dans tes insertions.
A mon humble avis, il faut regarder le code complet pour faire des optimisations (passage au POO si ce n'est pas déjà le cas, ajout de fonctions, ...)

Regarde du coté de ton serveur aussi, voir s'il est bien optimisé, et pas en surcharge de requete, idem pour la bande passante (je sais pas quelle genre de données tu envoies, mais on sait jamais).

Bref, je te souhaite bien du courage, car ça ne sera pas facile

ps : pour indexer une table de plusieurs clés, voici la commande SQL :
ALTER TABLE `ta_table` DROP PRIMARY KEY; -- enlève la clé primaire
ALTER TABLE `ta_table` ADD PRIMARY KEY ( `id1` , `id2` ) ; -- rajoute les clés primaires
0
Rejoignez-nous