Nimm alle IDs, wähle einen zufälligen aus und lade die ganze Zeile ein.
Wenn Sie wissen, dass die IDs ohne Löcher sequentiell sind, können Sie einfach die Max-Zahl nehmen und eine zufällige ID berechnen.
Wenn es hier und da Löcher gibt, aber meistens sequenzielle Werte, und Sie sich nicht um eine leicht verzerrte Zufälligkeit kümmern, greifen Sie den Maximalwert, berechnen Sie eine ID und wählen Sie die erste Zeile mit einer ID gleich oder höher als die du hast berechnet. Der Grund für die Verzerrung ist, dass IDs, die solchen Löchern folgen, eine höhere Wahrscheinlichkeit haben, ausgewählt zu werden als solche, die einer anderen ID folgen.
Wenn Sie nach dem Zufallsprinzip sortieren, haben Sie einen schrecklichen Table-Scan auf Ihren Händen und das Wort schnell trifft nicht auf eine solche Lösung zu.
Tun Sie das nicht, noch sollten Sie eine GUID bestellen, es hat das gleiche Problem.
Ich wusste, dass es eine Möglichkeit geben muss, dies in einer einzigen Abfrage auf schnelle Weise zu tun. Und hier ist es:
Ein schneller Weg ohne Einbeziehung von externem Code, ein großes Lob an
%Vor%MediaWiki verwendet einen interessanten Trick (für Wikipedia Special: Random-Funktion): die Tabelle mit den Artikeln hat eine zusätzliche Spalte mit einer Zufallszahl (generiert, wenn der Artikel erstellt wird). Um einen zufälligen Artikel zu erhalten, generieren Sie eine Zufallszahl und rufen Sie den Artikel mit dem nächstgrößeren oder kleineren Wert in der Zufallszahlenspalte ab. Mit einem Index kann dies sehr schnell sein. (Und MediaWiki ist in PHP geschrieben und für MySQL entwickelt.)
Dieser Ansatz kann ein Problem verursachen, wenn die resultierenden Zahlen schlecht verteilt sind; IIRC, das wurde in MediaWiki behoben, wenn du dich also dafür entscheidest, solltest du einen Blick auf den Code werfen, um zu sehen, wie er gerade ausgeführt wird (wahrscheinlich wird die Zufallszahlenspalte periodisch neu generiert).
Hier ist eine Lösung, die ziemlich schnell läuft und eine bessere zufällige Verteilung erhält, ohne von ID-Werten abhängig zu sein, die zusammenhängend sind oder bei 1 beginnen.
%Vor% Fügen Sie jeder Zeile eine Spalte hinzu, die einen berechneten zufälligen Wert enthält, und verwenden Sie diese in der Sortierklausel, wobei Sie bei der Auswahl auf ein Ergebnis beschränken. Dies funktioniert schneller als die Tabellensuche, die ORDER BY RANDOM()
verursacht.
Aktualisierung: Sie müssen immer noch einige zufällige Werte berechnen, bevor Sie die Anweisung SELECT
beim Abrufen ausgeben, z. B.
Ein einfacher, aber langsamer Weg wäre (gut für kleinere Tische)
%Vor%Im Pseudocode:
%Vor% Dies setzt voraus, dass id
ein eindeutiger (primärer) Schlüssel ist.
Es gibt eine andere Möglichkeit, um zufällige Zeilen mit nur einer Abfrage und ohne Reihenfolge von rand () zu erzeugen. Es beinhaltet benutzerdefinierte Variablen. Siehe zum Erstellen zufälliger Zeilen aus einer Tabelle
Um zufällige Zeilen aus einer Tabelle zu finden, verwenden Sie ORDER BY RAND () nicht, weil es MySQL zwingt, eine vollständige Dateisortierung durchzuführen und erst dann die erforderliche Anzahl von Zeilen zu ermitteln. Um diese vollständige Dateisortierung zu vermeiden, verwenden Sie die Funktion RAND () nur in der WHERE-Klausel. Es stoppt, sobald es die erforderliche Anzahl von Zeilen erreicht. Sehen Ссылка
Für die Auswahl mehrerer zufälliger Zeilen aus einer gegebenen Tabelle (zB "Wörter") hat unser Team diese Schönheit entwickelt:
%Vor%Die klassische "SELECT ID FROM Tabelle ORDER BY RAND () LIMIT 1" ist eigentlich in Ordnung.
Siehe folgenden Auszug aus dem MySQL-Handbuch:
Wenn Sie LIMIT row_count mit ORDER BY verwenden, beendet MySQL die Sortierung, sobald es die ersten row_count Zeilen des sortierten Ergebnisses gefunden hat, anstatt das gesamte Ergebnis zu sortieren.
Sehen Sie sich diesen Link von Jan Kneschke oder diese SO-Antwort , da beide die gleiche Frage diskutieren . Die SO-Antwort geht auch über verschiedene Optionen und hat einige gute Vorschläge, die auf Ihre Bedürfnisse abgestimmt sind. Jan geht auf die verschiedenen Möglichkeiten und Leistungsmerkmale ein. Er endet mit der folgenden optimierten Methode, um dies in einem MySQL-Select zu tun:
%Vor%HTH,
-Dipin
Ich bin ein wenig neu in SQL, aber wie wäre es mit einer Zufallszahl in PHP und mit
%Vor%Das löst das Problem mit Löchern in der Tabelle nicht.
Aber hier ist eine Wendung auf Lassevks Vorschlag:
%Vor%Verwenden Sie mysql_num_rows () in PHP, um eine Zufallszahl basierend auf dem obigen Ergebnis zu erstellen:
%Vor% Nebenbei bemerkt, wie langsam ist SELECT * FROM the_table
:
Erstellen Sie eine Zufallszahl basierend auf mysql_num_rows()
und verschieben Sie dann den Datenzeiger auf diesen Punkt mysql_data_seek()
. Wie langsam wird das auf großen Tischen mit sage und schreibe eine Million Zeilen sein?
Ich stieß auf das Problem, bei dem meine IDs nicht sequenziell waren. Was ich daraus gemacht habe.
%Vor%Die zurückgegebenen Zeilen sind ungefähr 5, aber ich beschränke sie auf 1.
Wenn Sie eine weitere WHERE-Klausel hinzufügen möchten, wird es etwas interessanter. Angenommen, Sie möchten nach Produkten mit Rabatt suchen.
%Vor%Was Sie tun müssen, ist sicherzustellen, dass Sie genug Ergebnis zurückgeben, weshalb ich es auf 100 gesetzt habe. Eine WHERE Rabatt & lt; .2 Klausel in der Unterabfrage war 10x langsamer, daher ist es besser, mehr Ergebnisse und Limits zurückzugeben .
Ich sehe hier eine Menge Lösung. Ein oder zwei scheint in Ordnung, aber andere Lösungen haben einige Einschränkungen. Aber die folgende Lösung wird für alle Situationen funktionieren:
%Vor%Hier, ID, muss nicht sequenziell sein. Es könnte jede Primärschlüssel- / Unique- / Autoinkrement-Spalte sein. Bitte beachten Sie die folgende Schnellste Möglichkeit zur Auswahl von a zufällige Reihe von einer großen MySQL-Tabelle
Danke Zillur - www.techinfobest.com
In meinem Fall hat meine Tabelle eine ID als Primärschlüssel, auto-increment ohne Lücken, also kann ich COUNT(*)
oder MAX(id)
verwenden, um die Anzahl der Zeilen zu erhalten.
Ich habe dieses Skript gemacht, um die schnellste Operation zu testen:
%Vor%Die Ergebnisse sind:
36.8418693542479 ms
0.241041183472 ms
0.216960906982 ms
Antwort mit der Bestellmethode:
%Vor%Ich habe das benutzt und der Job war erledigt die Referenz von hier
> %Vor%Erstellen Sie eine Funktion, um dies wahrscheinlich die beste Antwort und schnellste Antwort hier zu tun!
Pros - Funktioniert auch mit Lücken und extrem schnell.
%Vor%Bitte denken Sie daran, dass dieser Code nicht getestet wurde, aber ein funktionierendes Konzept ist, um zufällige Einträge auch mit Lücken zurückzugeben. Solange die Lücken nicht groß genug sind, um ein Ladezeitproblem zu verursachen.
Die Komplexität der ersten Abfrage ist O (1) für MyISAM-Tabellen.
Die zweite Abfrage wird von einem Tabellenscan begleitet. Komplexität = O (n)
Behalten Sie eine separate Tabelle nur für diesen Zweck. Sie sollten immer dieselben Zeilen in diese Tabelle einfügen, wenn Sie sie in die Originaltabelle einfügen. Annahme: Keine DELETEs.
%Vor%Wenn DELETEs erlaubt sind,
%Vor%Die Gesamtkomplexität ist O (1).