sql >> Database teknologi >  >> RDS >> Mysql

Optimering af langsom ORDER BY RAND()-forespørgsel

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().




  1. URL og linktekst fra databasen

  2. Hvordan afbrydes forbindelsen til en database og gå tilbage til standarddatabasen i PostgreSQL?

  3. Opdater db-tabel med en INT

  4. Hvis vi ændrer en primær nøgleværdi, hvorfor skal vi så ikke ændre en afhængig kolonneværdi?