Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Abrufen zufälliger Daten aus einer MySQL-Datenbank, aber keine Wiederholung von Daten

Das Auswählen zufälliger Zeilen ist immer schwierig, und es gibt keine perfekten Lösungen, die keine Kompromisse beinhalten. Beeinträchtigen Sie entweder die Leistung oder die zufällige Verteilung oder die Wahrscheinlichkeit, Duplikate auszuwählen usw.

Wie @JakeGould erwähnt, jede Lösung mit ORDER BY RAND() skaliert nicht gut. Je größer die Anzahl der Zeilen in Ihrer Tabelle wird, desto größer werden die Kosten für das Sortieren der gesamten Tabelle in einer Dateisortierung. Jake hat Recht, dass die Abfrage nicht zwischengespeichert werden kann, wenn die Sortierreihenfolge zufällig ist. Aber das interessiert mich nicht so sehr, weil ich normalerweise sowieso den Abfrage-Cache deaktiviere (er hat seine eigenen Skalierbarkeitsprobleme).

Hier ist eine Lösung, um die Zeilen in der Tabelle vorab zu randomisieren, indem Sie eine rownum-Spalte erstellen und eindeutige aufeinanderfolgende Werte zuweisen:

ALTER TABLE products ADD COLUMN rownum INT UNSIGNED, ADD KEY (rownum);
SET @rownum := 0;
UPDATE products SET rownum = (@rownum:[email protected]+1) ORDER BY RAND();

Jetzt können Sie eine zufällige Zeile durch eine Indexsuche erhalten, ohne Sortierung:

SELECT * FROM products WHERE rownum = 1;

Oder Sie können die nächste zufällige Zeile erhalten:

SELECT * FROM products WHERE rownum = 2;

Oder Sie können 10 zufällige Zeilen gleichzeitig oder eine beliebige andere Zahl ohne Duplikate erhalten:

SELECT * FROM products WHERE rownum BETWEEN 11 and 20;

Sie können jederzeit neu randomisieren:

SET @rownum := 0;
UPDATE products SET rownum = (@rownum:[email protected]+1) ORDER BY RAND();

Es ist immer noch kostspielig, das zufällige Sortieren durchzuführen, aber jetzt müssen Sie es nicht bei jeder SELECT-Abfrage tun. Sie können dies nach einem Zeitplan tun, hoffentlich außerhalb der Spitzenzeiten.