Zufalls-Datensatz nicht zufällig
Gast
- datenbank
0 suit0 GrandmasterA0 Matti Mäkitalo
Hallo,
in MySQL selektiere ich Datensätze und möchte aus dieser Menge zufällig einen auslesen. Unter Zufall verstehe ich, dass bei einer großen Zahl alle mal vorkommen, aber bei meinem Verfahren drängen sich drei oder vier immer in den Vordergrund, andere sind nie dabei:
SELECT
ort1.id ORT
...
FROM daten trm1
,orte ort1
WHERE trm1.owner_id = 1
AND trm1.emb_object IS NOT NULL
AND trm1.emb_object > ' '
AND trm1.intern_kz = 0
AND trm1.tag >= CURDATE()
AND ort1.id = trm1.ort_id
ORDER BY RAND() LIMIT 1
Wenn die letzte Zeile entfällt, habe ich 62 Treffer.
Was ist falsch?
Gruß, Gast
in MySQL selektiere ich Datensätze und möchte aus dieser Menge zufällig einen auslesen. Unter Zufall verstehe ich, dass bei einer großen Zahl alle mal vorkommen, aber bei meinem Verfahren drängen sich drei oder vier immer in den Vordergrund, andere sind nie dabei:
Was ist falsch?
Dein Wissen um "Zufall" in der der Datenverarbeitung - Pseudozufallszahlen sind leider selten wirklich zufällig :)
Ggf. ist aber einfach nur der Query-Cache vom SQL-Server dagegen.
Dein Wissen um "Zufall" in der der Datenverarbeitung - Pseudozufallszahlen sind leider selten wirklich zufällig :)
Mit anderen Worten: nicht wirklich zufällig, aber dafür konsistent "nicht zufällig" :)
Danke, habe SQL_NO_CACHE eingebaut. Schaun mer mal die näxten Tage.
Sind die Zufälle mit PHP besser? Alle 62 Treffer selektieren und PHP eine Zahl von 1 .. 62 generieren lassen?
Gruß, Gast
Sind die Zufälle mit PHP besser?
Das kommt drauf an, wie du das definierst - Zufallszahlen mit PHP sind jedenfalls "zufälliger" als die von MySQL, allerdings mit dem Nachteil, dass sie Abweichungen auf verschiedenen Plattformen haben.
Im Core kannst du dir das hier ansehen:
http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3_10/ext/standard/rand.c?revision=323023&view=markup
Bzw. hier, wie die gewöhnliche rand-Funktion arbeitet:
http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3_10/ext/standard/php_rand.h?revision=323023&view=markup
Hier sieht man z.B. sehr deutlich, dass unter Windows die Zufallszahl anders erzeugt wird als unter anderen Plattformen.
Alle 62 Treffer selektieren und PHP eine Zahl von 1 .. 62 generieren lassen?
Musst du ausprobieren was schneller geht und zufälliger ist:
Zu empfehlen ist im Fall von PHP jedenfalls mt_rand() und nicht rand(), da zweiteres bei häufigen aufruf schon entsprechend Muster erkennen lässt.
Am einfachsten ist das nachzuvollziehen, wenn man einfach in einer Schleife Zufallszahlen ausgeben lässt und diese dann in einer Kurve darstellt oder die häufigkeit auswertet.
aber bei meinem Verfahren drängen sich drei oder vier immer in den Vordergrund, andere sind nie dabei
Bei mir drängt sich bei ORDER BY RAND() immer der erste Datensatz nach vorn bzw. es kommt mir zumindest so vor. Ich hab das dann so gelöst, dass ich LIMIT 50,1 (je nachdem, wie viele Datensätze in der Tabelle sind... irgendwas mittendrin) nehme. Dadurch fällt mir sowas nicht mehr auf...
Gruß,
Andreas
Hi,
in MySQL selektiere ich Datensätze und möchte aus dieser Menge zufällig einen auslesen.
SELECT
ort1.id ORT
...
FROM daten trm1
,orte ort1
WHERE trm1.owner_id = 1
AND trm1.emb_object IS NOT NULL
AND trm1.emb_object > ' '
AND trm1.intern_kz = 0
AND trm1.tag >= CURDATE()
AND ort1.id = trm1.ort_id
ORDER BY RAND() LIMIT 1
Du wirst ggf. noch ein anderes Problem bekommen: deine Query ist potentiell recht langsam.
Das liegt daran, dass du deine Ergebnismenge komplett berechnen musst, dann komplett (de-)sortieren um dann genau einen Datensatz zu selektieren.
Wenn du weißt, dass keine Lücken in deinen IDs existieren, dann könntest du anhand einer Gleichverteilung darüber eine zufällige ID im Bereich {id\_min, ..., id\_max} selektieren und dann den kompletten Datensatz aus der DB abholen. Wenn es nur wenige Lücken gibt, dann könntest du beim Auftreffen einer Lücke einfach nochmal eine Zufallszahl ziehen, wenn es mehr Lücken werden, wird das aber auch langsam weil du dann viele misses bekommst.
Gibt noch ein paar Möglichkeiten mehr (z.B. nur IDs selektieren, PHP's rand() verwenden und dann mit der ID den ganzen Datensatz holen), aber man findet dazu einiges bei google.
Bis die Tage,
Matti
--
[Webapplikationen in C++ entwickeln](http://tntnet.org/)