Eviter des milliers de UPDATE


MarvinLeRouge
WRInaute impliqué
WRInaute impliqué
 
Messages: 526
Inscription: 1 Sep 2004

Message le Mar Sep 20, 2005 20:09

Question : cette colonne a-t-elle réellement une utilité, puisque le tri obtenu directement depuis le nombre de points donnera exactement le même résultat ?


mowmow
WRInaute impliqué
WRInaute impliqué
 
Messages: 975
Inscription: 3 Nov 2004

Message le Mer Sep 21, 2005 8:18

Après ma requête, j'enregistre le classement (updaté tous les jours à minuit) dans un fichier texte, et j'ai un lien "Voir ma position" qui transfère le joueur sur la page du classement où il apparaît ;)

spidetra
WRInaute passionné
WRInaute passionné
 
Messages: 1500
Inscription: 7 Juil 2003

Message le Mer Sep 21, 2005 9:26

J'ai une solution en 3 requêtes, avec création d'une table intermédiaire rank.
Il existe certainement une solution plus élégante.
Tu devras optimiser les index sur les tables,
et ensuite tester pour savoir si cette méthode est plus rapide ou pas, par rapport à des milliers d'update dans une boucle :

Cette solution gére les cas d'égalité :
- 2 membres ayant le même nbr de point ont le même rank

Structure des tables :
Code: Tout sélectionner
--
-- Structure de la table `membres`
--
CREATE TABLE `membres` (
  `login` varchar(50) NOT NULL default '',
  `rank` int(11) NOT NULL default '0',
  `points` int(11) NOT NULL default '0',
  PRIMARY KEY  (`login`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Contenu de la table `membres`
--

INSERT INTO `membres` VALUES ('Log1', 0, 55);
INSERT INTO `membres` VALUES ('Log2', 0, 12);
INSERT INTO `membres` VALUES ('Log3', 0, 55);
INSERT INTO `membres` VALUES ('Log4', 0, 28);
INSERT INTO `membres` VALUES ('Log5', 0, 45);
INSERT INTO `membres` VALUES ('Log6', 0, 150);
INSERT INTO `membres` VALUES ('Log7', 0, 5);
INSERT INTO `membres` VALUES ('Log8', 0, 3);

-- --------------------------------------------------------
--
-- Structure de la table `rank`
--

CREATE TABLE `rank` (
  `IDRank` int(11) NOT NULL auto_increment,
  `points` int(11) NOT NULL default '0',
  PRIMARY KEY  (`IDRank`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


Etape 1 : je vide la table rank.
Code: Tout sélectionner
TRUNCATE TABLE `rank`


Etape 2 : Insertion dans la table rank, des points des membres, avec un GROUP BY sur `points` pour tenir compte des ex-aequo
Code: Tout sélectionner
INSERT INTO `rank` ( `points` )
SELECT `points`
FROM membres
GROUP BY `points`
order by `points` desc


3. Mise à jour du rank de la table membre, en faisant une jointure sur le nombre de points de chaque membre.

Code: Tout sélectionner
UPDATE `membres`, `rank`
SET `rank` = `IDRank`
WHERE `membres`.`points` = `rank`.`points`


Résultat final :

Code: Tout sélectionner
Log6    1    150
Log1    2    55
Log3    2    55
Log5    3    45
Log4    4    28
Log2    5    12
Log7    6    5
Log8    7    3


Ce n'est certainement pas la meilleure solution, c'est juste une solution
Il faut tester les perfs sur des milliers d'enregistrement (pense aux index)
Dans la gestion des égalité, ne gère pas les "trous"
Est-ce que tu veux que Log5, ait comme rang 3, ou alors le rang 4 ( pour tenir compte de l'égalité sur le rang 2).


mowmow
WRInaute impliqué
WRInaute impliqué
 
Messages: 975
Inscription: 3 Nov 2004

Message le Mer Sep 21, 2005 12:32

Merci pour cette solution, mais en effet, une fonction serait plus rapide et moins compliquée :) Oui je préférerais que Log5 aie le rang 4 :)

Par contre le seul problème se pose au niveau des égalités dans la fonction ... Je ne sais pas comment je pourrais gérer ca correctement car en fait j'affiche 20 positions par page, et si 3 personne sont ex eaquo à la position 20,21,22 ... Je ne saurais pas la position exacte.

spidetra
WRInaute passionné
WRInaute passionné
 
Messages: 1500
Inscription: 7 Juil 2003

Message le Mer Sep 21, 2005 13:17

tient nous au courant quand tu auras trouvé ta solution,
et si elle n'est pas ultra confidentielle, poste là :)
à titre perso ça m'intéresse de savoir quelle solution tu auras implémenté


mowmow
WRInaute impliqué
WRInaute impliqué
 
Messages: 975
Inscription: 3 Nov 2004

Message le Mer Sep 21, 2005 19:45

Je pense en effet intégrer ta solution car avec une fonction, il y'a en effet le problème du ex eaquo ;)

spidetra
WRInaute passionné
WRInaute passionné
 
Messages: 1500
Inscription: 7 Juil 2003

Message le Jeu Sep 22, 2005 8:16

mowmow a écrit:Je pense en effet intégrer ta solution car avec une fonction, il y'a en effet le problème du ex eaquo ;)


Le pb des ex-aequo, n'est pas résolu avec la solution que j'ai proposée, il faudrat certainement l'adapter.

Le pb de la fonction, pour moi qui ne suis pas très doué en mathématiques, c'est qu'il faut trouver une bijection décroissante de I vers I, dont l'image est une séquence d'entier ( 1, 2, ......etc).
En fait je n'ai pas compris comment rank = points / max(points) pouvait ensuite être transformé en 1, 2, 3 ......
C'est pour ça que ta solution avec une fonction m'intéresse, ça me permettra de progresser
:D


mowmow
WRInaute impliqué
WRInaute impliqué
 
Messages: 975
Inscription: 3 Nov 2004

Message le Jeu Sep 22, 2005 16:54

spidetra a écrit:
mowmow a écrit:Je pense en effet intégrer ta solution car avec une fonction, il y'a en effet le problème du ex eaquo ;)


Le pb des ex-aequo, n'est pas résolu avec la solution que j'ai proposée, il faudrat certainement l'adapter.

Le pb de la fonction, pour moi qui ne suis pas très doué en mathématiques, c'est qu'il faut trouver une bijection décroissante de I vers I, dont l'image est une séquence d'entier ( 1, 2, ......etc).
En fait je n'ai pas compris comment rank = points / max(points) pouvait ensuite être transformé en 1, 2, 3 ......
C'est pour ça que ta solution avec une fonction m'intéresse, ça me permettra de progresser
:D


Oui c'est vrai en fait j'avais pas vu que ca donnerait pas les positions, j'ai un peu la tête ailleurs en ce moment.

Pour les problèmes d'ex-aequo j'ai pensé à cette solution : on met dans la table rank le nom du membre + les points, et après on récupère l'IDRank du membre pour l'update, ca marcherait bien comme ca non ?


mowmow
WRInaute impliqué
WRInaute impliqué
 
Messages: 975
Inscription: 3 Nov 2004

Message le Ven Sep 23, 2005 18:13

Et bien je confirme ca marche à merveille merci beaucoup ;)

Eviter des milliers de UPDATE

Si vous avez aimé cette discussion, partagez-la sur vos réseaux sociaux préférés :

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités