Re: Un enregistrement au hasard ?

From: "Daniel Verite" <daniel(at)manitou-mail(dot)org>
To: pgsql-fr-generale(at)postgresql(dot)org
Subject: Re: Un enregistrement au hasard ?
Date: 2008-11-13 12:15:52
Message-ID: c13bedef-0c31-4f1c-8ca9-e2ab0f31f6d3@mm
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-fr-generale

Sébastien Dinot wrote:

> Stephane Bortzmeyer a écrit :
> > L'excellent site StackOverflow a toujours vu un débat sur toute
> > question technique :-)
> >
> >
http://stackoverflow.com/questions/19412/how-to-request-a-random-row-in
-sql
>
> Je viens d'essayer la solution proposée en tête de page en effectuant
une
> adaptation minimaliste à PostgreSQL :
>
> SELECT *
> FROM personne
> WHERE id_personne >= RANDOM() * ( SELECT MAX(id_personne) FROM
personne )
> LIMIT 1;
>
> Ecrite ainsi, cette requête ne fonctionne pas très bien chez moi.

Cette méthode parait vraiment très mauvaise par rapport au besoin
d'obtenir une ligne aléatoire. (précision: je ne vois pas la page sur
stackoverflow car dans l'immédiat le site a l'air HS avec une erreur
http 503).

Si on essaie d'imaginer comment la requête pourrait être exécutée...
Mettons que sur une première exécution, le random()*max renvoie 500.
Donc on demande ça au moteur SQL:
SELECT * from personne where id_personne>=500 limit 1;
On peut imaginer que pour trouver le résultat, il se positionne sur une
page quelque part dans l'index, au début ou ailleurs selon comment il
est programmé (il peut aussi favoriser une page en cache), il lit une
valeur de id_personne, et si elle est supérieure il s'arrête là. Aucun
besoin d'aller plus loin puisqu'un résultat satisfaisant est trouvé et
qu'il y a un LIMIT 1.

Mettons que sur une deuxième exécution, le random()*max renvoie 400.
Maintenant on demande ça au moteur SQL:
SELECT * from personne where id_personne>=400 limit 1;
Il se positionne encore sur une page dans l'index, typiquement la même
qu'avant parce qu'aucune raison de changer, lit une valeur de
id_personne, trouve la même qu'avant, qui étant supérieure à 500, est a
fortiori supérieur à 400. Et donc il renvoie à nouveau cette même
valeur puisqu'elle satisfait au critère.

Et on peut imaginer qu'il sorte comme ça le même résultat N fois de
suite, sans que ce soit du tout choquant ni improbable. Ca veut juste
dire que le caractère aléatoire de cette méthode est inexistant :)

--
Daniel
PostgreSQL-powered mail user agent and storage:
http://www.manitou-mail.org

In response to

Browse pgsql-fr-generale by date

  From Date Subject
Next Message Guillaume Lelarge 2008-11-14 17:24:07 Re: PGXMl?
Previous Message Sébastien Dinot 2008-11-12 23:12:05 Re: Un enregistrement au hasard ?