Le générateur de nombres pseudo-aléatoires MySQL est complètement déterministe. Les docs disent :
Il ne peut pas utiliser /dev/random car MySQL est conçu pour fonctionner sur une variété de systèmes d'exploitation, dont certains n'ont pas de /dev/random.
MySQL initialise une graine par défaut au démarrage du serveur, en utilisant l'entier renvoyé par time(0)
.Si vous êtes intéressé par la ligne source, elle se trouve dans le source MySQL dans le fichier sql/mysqld.cc, fonction init_server_components()
. Je ne pense pas qu'il se réensemence jamais.
Ensuite, les nombres "aléatoires" suivants sont basés uniquement sur la graine. Voir le fichier source mysys_ssl/my_rnd.cc, fonction my_rnd()
.
La meilleure solution pratique à votre tâche de sélection aléatoire, à la fois pour les performances et la qualité de la randomisation, consiste à générer une valeur aléatoire entre la valeur de clé primaire minimale et la valeur de clé primaire maximale. Utilisez ensuite cette valeur aléatoire pour sélectionner une clé primaire dans votre table :
SELECT ... FROM MyTable WHERE id > $random LIMIT 1
La raison pour laquelle vous utiliseriez> au lieu de =est que vous pourriez avoir des lacunes dans l'id en raison de la suppression ou de l'annulation de lignes, ou vous pourriez avoir d'autres conditions dans votre clause WHERE afin que vous ayez des lacunes entre les lignes qui correspondent à vos conditions .
Les inconvénients de cette méthode supérieure à :
- Les lignes suivant un tel écart ont plus de chances d'être choisies, et plus l'écart est grand, plus les chances sont grandes.
- Vous devez connaître le MIN(id) et le MAX(id) avant de générer la valeur aléatoire.
- Ne fonctionne pas aussi bien si vous avez besoin de plusieurs lignes aléatoires.
Avantages de cette méthode :
- C'est beaucoup plus rapide que ORDER BY RAND(), même pour une taille de table modeste.
- Vous pouvez utiliser une fonction aléatoire en dehors de SQL.