Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment fonctionne ORDER BY RAND() de MySQL ?

Bien qu'il n'existe pas de "commande rapide par rand()", il existe une solution de contournement pour votre tâche spécifique.

Pour obtenir une seule ligne aléatoire , vous pouvez faire comme ce blogueur allemand :http://web.archive.org/web/20200211210404/http://www.roberthartung.de/mysql-order-by-rand-a- étude-de-cas-des-alternatives/ (Je n'ai pas pu voir d'URL de lien. Si quelqu'un en voit un, n'hésitez pas à modifier le lien.)

Le texte est en allemand, mais le code SQL est un peu en bas de la page et dans de grandes cases blanches, donc ce n'est pas difficile à voir.

Fondamentalement, ce qu'il fait, c'est créer une procédure qui permet d'obtenir une ligne valide. Cela génère un nombre aléatoire entre 0 et max_id, essayez de récupérer une ligne, et si elle n'existe pas, continuez jusqu'à ce que vous en trouviez une qui existe. Il permet de récupérer x nombre de lignes aléatoires en les stockant dans une table temporaire, vous pouvez donc probablement réécrire la procédure pour être un peu plus rapide en récupérant une seule ligne.

L'inconvénient est que si vous supprimez BEAUCOUP de lignes et qu'il y a d'énormes lacunes, il y a de grandes chances qu'il manque des tonnes de fois, ce qui le rend inefficace.

Mise à jour :différents temps d'exécution

Cela peut être lié à l'indexation. id est indexé et rapide d'accès, tandis que l'ajout de username au résultat, signifie qu'il doit lire cela à partir de chaque ligne et le mettre dans la table mémoire. Avec le * il doit également tout lire en mémoire, mais il n'a pas besoin de parcourir le fichier de données, ce qui signifie qu'il n'y a pas de temps perdu à chercher.

Cela ne fait une différence que s'il y a des colonnes de longueur variable (varchar/texte), ce qui signifie qu'il doit vérifier la longueur, puis ignorer cette longueur, au lieu de simplement ignorer une longueur définie (ou 0) entre chaque ligne.