ORDER BY RAND()
er langsom, fordi DBMS skal læse alle rækker, sortere dem alle, bare for kun at beholde nogle få rækker. Så ydeevnen af denne forespørgsel afhænger i høj grad af antallet af rækker i tabellen og falder, efterhånden som antallet af rækker stiger.
Der er ingen måde at optimere det på.
Der er dog alternativer:
Du kan implementere "få 5 tilfældige rækker" ved at lave 6 forespørgsler:
- hent antallet af rækker i tabellen (du kan cache denne)
-
lav 5 forespørgsler med
OFFSET <random offset from 0 to $number_of_rows-1> LIMIT 1
(dvs. læs og returner kun én række fra en tilfældig offset)For eksempel:
SELECT * FROM Products OFFSET 42 LIMIT 1
(bemærk:uden at deltage, indtil videre)Sådanne forespørgsler er meget hurtige og kører på en tid, der er praktisk talt uafhængig af tabellens størrelse.
Det burde være meget hurtigere end ORDER BY RAND()
.
For nu at få et tilfældigt billede for hvert tilfældigt produkt:
SELECT *
FROM (
SELECT *
FROM Products
OFFSET 42 LIMIT 1
) p
JOIN ProductImages pi
ON pi.product_id = p.id
ORDER BY RAND()
LIMIT 1
Den indre forespørgsel er stadig hurtig, og den ydre sorterer kun få rækker (forudsat at der er få billeder pr. produkt), og kan derfor stadig bruge rækkefølge efter rand().