MYSQL - Abfrage RAND() dauert zu lange

Skid

Erfahrenes Mitglied
Hallo,

ich möchte aus einer Datenbank Tabelle (mit ca. 31 Millionen Einträgen) ca. 100.000 bis 500.000 Einträge zufällig auswählen. Die Einträge sollen in einer anderen Tabelle gespeichert werden.

Ich habe jedoch das Problem dass ich mittels ...
Code:
SELECT * FROM table WHERE 1 ORDER BY RAND() LIMIT 100000;
... bis morgen früh und noch viel länger sitzen müsste.

Die Anfrage mit 5.000 Einträgen dauert schon bald eine halbe Stunde und so richtig effiktiv ist das nun auch nicht, da ich nicht immer 30 Minuten für 5.000 Einträge warten kann.

Kennt jemand eine Alternative dazu ?

Beste Grüße und Danke,
SkiD.
 
Das ist ein bekanntes Problem, denn ORDER BY RAND() ist in keiner Weise optimiert. Viel mehr wird für jede Spalte die Funktion aufgerufen und anschließend muss das ganze komplett sortiert wird. Bei 31 Millionen Einträgen kann man sich vorstellen, dass die nicht alle in den RAM passen und selbst wenn, dauert das sortieren schon eine gewisse Zeit. Im Prinzip wird das Betriebssystem nur mit Paging beschäftigt sein. Wie groß dein "LIMIT" am Ende ist, spielt kaum keine Rolle. Sortiert werden müssen immer ALLE.

Die Frage ist erst mal, was du mit 100000 zufällig gewählten Einträgen willst?

Wenn du einfach nur eine andere Tabelle damit befüllen willst, sollte das hier wesentlich schneller sein:

SQL:
INSERT INTO			table_2
SELECT				*
FROM				table_1
WHERE				RAND() < 0.016129

Das sollte ungefähr 500000 Einträge auswählen (0.016129 = 500000/31000000).
 
Hallo,

na klasse. ^^
Das ist dann wohl weniger toll ...

Ich brauche zufällige Einträge, weil ich die Einträge für ein Statistikprogramm benötige, welches mit den Einträgen arbeiten muss. D.h. die Einträge müssen zufällig sein, damit die Reihenfolge nicht das Ergebnis verfälscht.

Sollte die Geschichte 500000 Einträge auswählen welche zufällig soritert sind ? Oder nimmt er einfach nur die ersten Einträge ?
 
Mein Code wählt ebenfalls zufällige Datensätze aus und fügt Sie in eine neue Tabelle. Es wird genauso wie bei deiner Abfrage für jede Zeile RAND() aufgerufen, aber es muss anschließend nicht sortiert werden. Statistisch gesehen sollte bei etwa 500000 Datensätzen der Wert Kleiner als 0.016129 sein und diese erscheinen dann im Ergebnis.
 
Hallo,
Code:
SELECT * FROM table WHERE 1 ORDER BY RAND() LIMIT 100000;

Du musst deine Abfrage so umbauen, dass du einen Index zum Suchen nutzen kannst, also in der WHERE Klausel. Ohne Index in einer so großen Tabelle zu lesen, kannst du knicken.

Du könntest zum Beispiel einen UNIQUE INDEX auf eine Spalte mit fortlaufenden Nummern setzen. Es würde z.B. auch ein Auto Increment Wert als Primärschlüssel gehen. Dann nimmst du die Werte der Spalte, lässt dir daraus 100.000 zufällige Werte zurückgeben und suchst dann nach den Datensätzen mit diesen Nummern. Am besten führst du danach in einer Schleife folgendes aus:

SELECT feld1, feld2, ... , feldN FROM table WHERE nummer IN (1,3,7...,13322,3213214);

Jeweils mit 10.000 Nummern, damit es noch performant bleibt.

Das nur als Beispiel.
 
Zuletzt bearbeitet:
Zurück