554 votes

MySQL sélectionner 10 lignes aléatoires de 600K lignes rapides

Comment puis-je mieux d'écrire une requête qui sélectionne les 10 lignes au hasard à partir d'un total de 600k?

450voto

Riedsio Points 4500

Un grand poste de manutention plusieurs cas, des simples, des lacunes, à la non-uniforme avec des lacunes.

http://jan.kneschke.de/projects/mysql/order-by-rand/

Pour la plupart des cas général, voici comment faire:

SELECT name
  FROM random AS r1 JOIN
       (SELECT CEIL(RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1

Cela suppose que la distribution de l'id est égal à égal, et qu'il peut y avoir des lacunes dans la liste des id. Voir l'article des exemples plus avancés

437voto

Preetam Purbia Points 1070
SELECT column FROM table
ORDER BY RAND()
LIMIT 10

17voto

snippetsofcode Points 374

Je reçois des requêtes rapides (de l'ordre de 0.5 secondes) avec un cpu lent, la sélection aléatoire de 10 raws dans un 400K de registres de base de données MySQL non mis en cache de taille de 2 go. Voir ici mon code: une sélection Rapide des lignes aléatoires dans MySQL

<?php
$time= microtime_float();

$sql='SELECT COUNT(*) FROM pages';
$rquery= BD_Ejecutar($sql);
list($num_records)=mysql_fetch_row($rquery);
mysql_free_result($rquery);

$sql="SELECT id FROM pages WHERE RAND()*$num_records<20
   ORDER BY RAND() LIMIT 0,10";
$rquery= BD_Ejecutar($sql);
while(list($id)=mysql_fetch_row($rquery)){
    if($id_in) $id_in.=",$id";
    else $id_in="$id";
}
mysql_free_result($rquery);

$sql="SELECT id,url FROM pages WHERE id IN($id_in)";
$rquery= BD_Ejecutar($sql);
while(list($id,$url)=mysql_fetch_row($rquery)){
    logger("$id, $url",1);
}
mysql_free_result($rquery);

$time= microtime_float()-$time;

logger("num_records=$num_records",1);
logger("$id_in",1);
logger("Time elapsed: <b>$time segundos</b>",1);
?>

11voto

The Surrican Points 12882

Eh bien, si vous n'avez pas de lacunes dans vos touches et ils sont tous numériques, vous pouvez calculer les nombres aléatoires et de sélectionner les lignes. mais ce ne sera probablement pas le cas. Donc, une solution pourrait être la suivante:

SELECT * FROM table WHERE key >= FLOOR(RAND()*MAX(id)) LIMIT 1

qui va s'assurer que vous obtenez un nombre aléatoire, il int gamme de vos clés et ensuite vous sélectionner le meilleur qui est plus grand. vous ahve pour ce faire, 10 fois.

cependant, ce n'est PAS vraiment reandom parce que vos clés de brume susceptibles de ne pas être uniformément réparti.

c'est vraiment un gros problème et pas facile à résoudre remplissant l'ensemble de ces exigences, mysqls rand() est le meilleur youc un obtenir si vous voulez vraiment 10 lignes aléatoires.

il existe cependant une autre solution qui est rapide, mais a également un tradoff quand il s'agit de l'aléatoire, mais peut vous conviennent le mieux. lire à ce sujet ici: Comment puis-je optimiser MySQL COMMANDE PAR la fonction RAND ()?

la question est de savoir comment aléatoire avez-vous besoin de l'être.

pouvez-vous nous expliquer un peu plus pour que je puisse vous donner une bonne solution.

par exemple, une entreprise, j'ai travaillé avec une solution où ils avaient besoin absolu de l'aléatoire extrêmement rapide. ils ont terminé avec pré remplissage de la base de données avec des valeurs aléatoires qui ont été sélectionnés de la descente et du configuré pour différentes valeurs aléatoires ensuite à nouveau.

si vous avez à peine jamais de mise à jour vous pouvez également remplir une incrémentation id si vous n'avez pas de lacunes et juste peut calculer des clés avant de choisir... cela dépend du cas d'utilisation!

10voto

user1931858 Points 710

Comment sélectionner des lignes aléatoires à partir d'une table:

À partir d'ici: Sélectionnez lignes aléatoires dans MySQL

Une rapide amélioration par rapport "analyse de la table" est d'utiliser l'index pour ramasser aléatoire id.

SELECT *
FROM random, (
        SELECT id AS sid
        FROM random
        ORDER BY RAND( )
        LIMIT 10
    ) tmp
WHERE random.id = tmp.sid;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X