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

Ottimizzazione della query ORDER BY RAND() lenta

ORDER BY RAND() è lento perché il DBMS deve leggere tutte le righe, ordinarle tutte, solo per mantenere solo poche righe. Pertanto, le prestazioni di questa query dipendono fortemente dal numero di righe nella tabella e diminuisce all'aumentare del numero di righe.

Non c'è modo di ottimizzarlo.

Ci sono comunque delle alternative:

Puoi implementare "ottieni 5 righe casuali" eseguendo 6 query:

  • ottieni il numero di righe nella tabella (puoi memorizzarla nella cache)
  • fai 5 query con OFFSET <random offset from 0 to $number_of_rows-1> LIMIT 1 (cioè leggere e restituire solo una riga da un offset casuale)

    Ad esempio:SELECT * FROM Products OFFSET 42 LIMIT 1 (nota:senza aderire, per ora)

    Tali query sono molto veloci e vengono eseguite in un tempo praticamente indipendente dalle dimensioni della tabella.

Dovrebbe essere molto più veloce di ORDER BY RAND() .

Ora, per ottenere un'immagine casuale per ogni prodotto casuale:

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

La query interna è ancora veloce e quella esterna sta ordinando solo poche righe (supponendo che ci siano poche immagini per prodotto), quindi può ancora utilizzare order by rand().