RAND() : Dans ou hors SQL ?

Sep 2010ven 3
Tiens je lisais un truc

Citation de la faq php du SdZ :

Comment sélectionner une ligne au hasard dans une table ?
Réponse:
En se servant de la fonction RAND() de MySQL.
Cette requête est à utiliser sur des tables peu fournies, plus vos tables seront conséquentes, et plus le temps de réponses de MySQL sera long


Et moi c'est le attention qui m'a interpellé... Me voilà donc parti pour un test sur une table de mes bases locales Sélectionner juste un id sur une table de 3000 enregistrement environ; le tout réalisé 10000 fois pour avoir une bonne comparaison.
1er cas :
SELECT `id` FROM `table` ORDER BY RAND() LIMIT 1;
2nd cas :
SELECT `id` FROM `table` WHERE `id`=$rand_defini_par_php;

Roulements de tambour... Le grand gagnant est le rand() défini par php :
Cas 1 : 25 secondes environ
Cas 2 : 0,5 secondes environ, soit 50 fois moins


Il y a donc 5ms d'écart entre chacune des opérations.



Voici le code de test pour vérifier Par contre, vu le temps requis il faut faire attention aux 30s d'exécution de php, on peut passer le script en console pour éviter ça.
<?php
mysql_connect('host','user','pass');
mysql_select_db('base');
function get_ms()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}

$debut_boucle_1=get_ms();
for($i=1;$i<=10000;$i++):
mysql_query('SELECT id from table order by rand() limit 1');

$fin_boucle_1=get_ms();
$temps_1=($fin_boucle_1-$debut_boucle_1);
echo '========= RAND dans BDD : '.$temps_1."\n";

$debut_boucle_2=get_ms();
$res = mysql_fetch_assoc(mysql_query('SELECT COUNT(id) as total from table'));
for($i=1;$i<=10000;$i++):
$rand = floor(rand(1,$res['total']));
mysql_query('SELECT id from table WHERE id='.$rand);
endfor;

$fin_boucle_2=get_ms();
$temps_2=($fin_boucle_2-$debut_boucle_2);
echo '========= RAND hors BDD : '.$temps_2."\n";
?>
Infos

Auteur : Jef

Catégorie : Actualité politique

Commentaires : 10 - Voir

Partage

fb Twit'it

Par : Jef - Le 3 Septembre 2010 à 17h58
C'est pour ça que je faisais l'expérience pour illustrer le bout de quote qui dit "attention aux requêtes sur grosses tables".
Évidemment que ce qui se passe n'est pas pareil.
Par : Seb - Le 3 Septembre 2010 à 17h49
Alors moi je serais pas trop d'accord avec ce test, car tu compare 2 choses différentes (meme si au final le resultat est bien là) :
Dans la 1ere methode, tu fait :
mysql_query('SELECT id from table order by rand() limit 1');
Donc théoriquement tu les selectionne TOUT, tu les range dans l'ordre avec ORDER et tu ne récupère que le premier avec Limit 1.

Alors que dans la seconde methode tu en prend bien qu'un seul a chaque boucle.

Donc forcément la 1ère est plus longue, mais c'est normal car elle fait beaucoup plus de travail
(elle stock tout dans un tableau en mémoire)
Par : Jef - Le 3 Septembre 2010 à 14h43
putain de moi, je n'avais pas modifié le bon fichier, ça m'apprendra à commenter mon code plus sérieusement

M'enfin c'est réglé maintenant
Par : Mickael - Le 3 Septembre 2010 à 14h26
Voici comment je fonctionne :
Sauver dans la base de données :
mysql_real_escape_string(stripslashes(trim($commentaire)));
Afficher dans la page :
nl2br(htmlspecialchars(stripslashes(trim($commentaire)), ENT_COMPAT, 'UTF-8'));
Afficher dans un formulaire :
htmlspecialchars(stripslashes(trim($string)), ENT_COMPAT, 'UTF-8');
Par : Jef - Le 3 Septembre 2010 à 14h18
Ben effectivement, merde alors o_0

J'ai bien nl2br, mais apparement ça coince :s
A suivre...
Par : Mickael - Le 3 Septembre 2010 à 14h14
Tiens, tu devrais mettre cette fonction pour afficher les commentaires :

nl2br(htmlspecialchars(stripslashes(trim($commentaire)), ENT_COMPAT, 'UTF-8'));
Par : Mickael - Le 3 Septembre 2010 à 14h11
Bon tant pis pour le script tu devrait mettre la fonction nl2br() pour les commentaires (ou mieux

Alors
$rand = rand(0,9999)
requete :
mysql_query('SELECT id from table LIMIT $rand,1');
Par : Jef - Le 3 Septembre 2010 à 14h11
Ouais, mais en même temps c'était pour faire un test, donc les id ils sont tous là dans ma table
Par : Mickael - Le 3 Septembre 2010 à 14h09
Certes, le rand de PHP est plus rapide. Mais ton script n'est pas adapté si des "id" sont manquants.

Je propose plutôt ca :
Par : Mickael - Le 3 Septembre 2010 à 14h08
Certes, le rand de PHP est plus rapide. Mais ton script n'est pas adapté si des "id" sont manquants.

Je propose plutôt ca :
Ajouter un commentaire

jfrigollot.com/blog - © 2010 - Une réalisation JFRWeb - Mentions légales