Comment puis-je mieux d'écrire une requête qui sélectionne les 10 lignes au hasard à partir d'un total de 600k?
Réponses
Trop de publicités?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
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);
?>
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!
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;