Exclure un chiffre d'un rand()

Répondre
BigZ[SHN]
le 21/04/2008 à 16:43
BigZ[SHN]
Bonjour,

J'ai une galerie de photo et sur mon index.php j'affiche :

La dernière photo
et
Une photo au hasard

Pour la photo au hasard j'ai utilisé "ORDER BY rand() LIMIT 1"

Ca fonctionne, simplement mon souci c'est que parfois, il affiche 2x la même photo (si le rand va chercher ma dernière photo ajoutée)

Est-til possible d'exclure du rand l'id de ma dernière photo, ou l'id de la photo affichée plus haut ?

Merci
lordgun
le 21/04/2008 à 18:25
lordgun
Attention, c'est très mauvais de faire des ORDER BY RAND(): super pratique parce que c'est simple, mais si ta table est grande tu ne vais jamais t'en sortir: MySQL va faire un RAND() (opération lourde) pour chacune des rows !

-> prends les ID de tes photos via PHP, tu fais 1 rand() en php, et tu vas chercher l unique photo qui correspond en mysql.
LA GLOBULE
le 21/04/2008 à 20:23
LA GLOBULE
lordgun : exact, mais c'est le genre de chose qu'on apprend quand on traite des tables de X go :) Ce n'est pas le cas de tout le monde ici :p

Mais c'est vrai que les bonnes pratiques sont à apprendre dès le départ.
LupusMic
le 22/04/2008 à 00:47
LupusMic
(lordgun) Le problème revient au même, sauf que tu rajoutes une lourdeur supplémentaire en rapatriant les données dans le client MySQL.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
JuTs
le 22/04/2008 à 12:26
JuTs
Autre suggestion :

S'arranger pour que les photos dans la table aient des ID uniques et consécutif.
Du côté PHP générer un nombre aléatoire entre 1 et le nombre de photos. Et finalement récupérer la photo correspondante. Il y a toujours deux requête mais seul le nombre de photo est récupéré
JuTs
BigZ[SHN]
le 22/04/2008 à 16:54
BigZ[SHN]
Merci La Globule pour la solution.

On pense toujours a faire un WHERE = et jamais un WHERE <>...psychologiquement c'est dur...lol

Pour ce qui est du rand() dans la requete, vous dites qu'il faut éviter cela lorsqu'on à une table de plusieurs Go ? Donc sur une table qui va contenir quelques milliers d'entre c'est pas grave non ?
lordgun
le 22/04/2008 à 16:58
lordgun
@LupusMic:
non pas du tout, le problème est complétement différent...

si tu as une table de 10 000 entrées... order by rand() va sortir 10 000 nombres aléatoires.

or, tu selectionnes les id de tes data, tu les mets dans un tableau associatif php qui comme a 0, puis tu fais un seul mt_rand(), de 0 à la taille de ton tableau... et tu recuperes l id en face, que tu transmets a mysql: tu as ton resultat aléatoire avec un seul rand()
LupusMic
le 22/04/2008 à 21:10
LupusMic
Avec la méthode rand :
- le script PHP créé une requête et la soumet au serveur MySQL
- le serveur MySQL effectue l'opération suivante :
Using where; Using index; Using temporary; Using filesort

- le résultat est préparé
- tu l'envoie au script PHP
- tu traite le tuple pour affichage

avec la méthode select id :
- tu envoie la requête
- le serveur MySQL prépare tous les résultats possible
- l'ensemble de résultats transite sur le réseau
- le script PHP stocke les résultats dans un tableau
- le script PHP lit l'id en fonction d'une position aléatoire
- le script PHP écrit une nouvelle requête SQL et l'envoie au serveur
- etc.

Je ne sais pas laquelle des deux méthodes est efficace, les deux me semblent inefficace, même si j'ai tendance à privilégier la solution avec le rand dans la requête SQL car l'ensemble de la manipulation des données est effectuée dans MySQL, ce qui est son rôle.

Maintenant, si la génération d'un nombre aléatoire pose vraiment problème, ce dont je doute, il serait toujours temps de trouver une astuce (avec une table aléatoire de référence par exemple).

J'ai pour principe de faire simple, et d'optimiser si nécessaire. L'optimisation précoce est un piège :)
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
LA GLOBULE
le 22/04/2008 à 21:34
LA GLOBULE
Oui, les deux méthodes sont crappy en soit.
Mais je sais par expérience, lordgun également (on a bossé ensemble sur des tables à X millions d'enregistrements), que le order by rand, ben mysql, il kiffe pas du tout.

Pour t'en convaincre, je te propose cet article (qui d'ailleurs propose une solution que je trouve fort astucieuse).
Répondre
LoadingChargement en cours