554 Stimmen

MySQL wähle 10 zufällige Zeilen aus 600.000 Zeilen schnell

Wie kann ich am besten eine Abfrage schreiben, die 10 Zeilen zufällig aus insgesamt 600.000 auswählt?

19 Stimmen

Hier sind 8 Techniken; vielleicht funktioniert eine davon gut in Ihrem Fall.

0 Stimmen

(Das sind tatsächlich 5 Techniken -- einige waren keine Verbesserungen.)

1voto

Nicolas Cohen Punkte 306

Ein Weg, den ich ziemlich gut finde, wenn es eine automatisch generierte ID gibt, ist die Verwendung des Modulo-Operators '%'. Zum Beispiel, wenn Sie 10.000 zufällige Datensätze aus 70.000 benötigen, könnten Sie dies vereinfachen, indem Sie sagen, dass Sie 1 von jeweils 7 Zeilen benötigen. Dies kann in dieser Abfrage vereinfacht werden:

SELECT * FROM 
    table 
WHERE 
    id % 
    FLOOR(
        (SELECT count(1) FROM table) 
        / 10000
    ) = 0;

Wenn das Ergebnis aus der Division der Zielzeilen durch die insgesamt verfügbaren nicht ganzzahlig ist, haben Sie einige zusätzliche Zeilen, als Sie angefordert haben. Daher sollten Sie eine LIMIT-Klausel hinzufügen, um Ihnen zu helfen, das Ergebnis zu trimmen, wie folgt:

SELECT * FROM 
    table 
WHERE 
    id % 
    FLOOR(
        (SELECT count(1) FROM table) 
        / 10000
    ) = 0
LIMIT 10000;

Dies erfordert zwar einen vollständigen Scan, ist jedoch schneller als ORDER BY RAND und meiner Meinung nach einfacher zu verstehen als andere in diesem Thread erwähnte Optionen. Auch wenn das System, das in die DB schreibt, Zeilensätze in Stapeln erstellt, erhalten Sie möglicherweise nicht das so zufällige Ergebnis, wie Sie es erwartet hatten.

2 Stimmen

Jetzt, wo ich darüber nachdenke, wenn Sie jedes Mal zufällige Zeilen benötigen, wenn Sie es aufrufen, ist dies nutzlos. Ich dachte nur über die Notwendigkeit nach, zufällige Zeilen aus einem Satz zu erhalten, um einige Forschungen durchzuführen. Ich denke immer noch, dass der Modulo eine gute Sache ist, um im anderen Fall zu helfen. Sie könnten den Modulo als ersten Durchgangsfilter verwenden, um die Kosten einer ORDER BY RAND-Operation zu senken.

0voto

WÄHLEN SIE
  * 
AUS
  table_with_600k_rows
WO
  RAND( ) 
ORDER BY
  id DESC 
LIMIT 30;

id ist der Primärschlüssel, sortiert nach id, ERKLÄREN SIE table_with_600k_rows, finden Sie heraus, dass die Zeile nicht die gesamte Tabelle durchsucht

0voto

GeniusGeek Punkte 325

Ich denke, hier ist ein einfacher und dennoch schnellerer Weg, den ich auf dem Live-Server getestet habe im Vergleich zu einigen der obigen Antworten und es war schneller.

 SELECT * FROM `table_name` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table_name` ) ORDER BY id LIMIT 30; 

//Dauerte 0,0014 Sekunden bei einer Tabelle mit 130 Zeilen

SELECT * FROM `table_name` WHERE 1 ORDER BY RAND() LIMIT 30

//Dauerte 0,0042 Sekunden bei einer Tabelle mit 130 Zeilen

 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 30

//Dauerte 0,0040 Sekunden bei einer Tabelle mit 130 Zeilen

-2voto

josejavierfm Punkte 135

Ich verwende diese Abfrage:

select floor(RAND() * (SELECT MAX(key) FROM table)) from table limit 10

Abfragezeit: 0.016s

0 Stimmen

Durch die obige Abfrage erhalten Sie Zeilen wie 4, 7, 14, 11, die unzureichend sind!

-3voto

Bernardo Siu Punkte 1341

So mache ich es:

select * 
from table_with_600k_rows
where rand() < 10/600000
limit 10

Ich mag es, weil es keine anderen Tabellen benötigt, einfach zu schreiben ist und sehr schnell ausgeführt wird.

5 Stimmen

Das ist eine volle Tabellendurchsuchung und es verwendet keine Indexe. Für große Tabellen und eine vielbeschäftigte Umgebung ist das ein absolutes No-Go.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X