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

Optimierung der langsamen ORDER BY RAND()-Abfrage

ORDER BY RAND() ist langsam, weil das DBMS alle Zeilen lesen und sortieren muss, nur um nur ein paar Zeilen zu behalten. Die Leistung dieser Abfrage hängt also stark von der Anzahl der Zeilen in der Tabelle ab und nimmt ab, wenn die Anzahl der Zeilen zunimmt.

Es gibt keine Möglichkeit, das zu optimieren.

Es gibt jedoch Alternativen:

Sie können "get 5 random rows" implementieren durch 6 Abfragen:

  • Anzahl der Zeilen in der Tabelle erhalten (Sie können diese zwischenspeichern)
  • Führen Sie 5 Abfragen mit OFFSET <random offset from 0 to $number_of_rows-1> LIMIT 1 durch (d.h. nur eine Zeile von einem zufälligen Offset lesen und zurückgeben)

    Zum Beispiel:SELECT * FROM Products OFFSET 42 LIMIT 1 (Anmerkung:vorerst ohne Beitritt)

    Solche Abfragen sind sehr schnell und laufen praktisch unabhängig von der Tabellengröße.

Das sollte viel sein schneller als ORDER BY RAND() .

Um nun ein zufälliges Bild für jedes zufällige Produkt zu erhalten:

SELECT *
FROM (
    SELECT *
    FROM Products
    OFFSET 42 LIMIT 1
) p
JOIN ProductImages pi
ON   pi.product_id = p.id
ORDER BY RAND()
LIMIT 1

Die innere Abfrage ist immer noch schnell und die äußere sortiert nur wenige Zeilen (unter der Annahme, dass es wenige Bilder pro Produkt gibt), und kann daher immer noch order by rand() verwenden.