sql >> Databasteknik >  >> RDS >> Mysql

Optimerar långsam ORDER BY RAND()-fråga

ORDER BY RAND() är långsam eftersom DBMS måste läsa alla rader, sortera dem alla, bara för att behålla ett fåtal rader. Så prestandan för den här frågan beror mycket på antalet rader i tabellen och minskar när antalet rader ökar.

Det finns inget sätt att optimera det.

Det finns dock alternativ:

Du kan implementera "få 5 slumpmässiga rader" genom att göra 6 frågor:

  • få antal rader i tabellen (du kan cachelagra den här)
  • gör 5 frågor med OFFSET <random offset from 0 to $number_of_rows-1> LIMIT 1 (dvs läs och returnera endast en rad från någon slumpmässig offset)

    Till exempel:SELECT * FROM Products OFFSET 42 LIMIT 1 (obs:utan att gå med, för tillfället)

    Sådana frågor är mycket snabba och körs på en tid som är praktiskt taget oberoende av tabellstorleken.

Det här borde vara mycket snabbare än ORDER BY RAND() .

Nu, för att få en slumpmässig bild för varje slumpmässig 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 inre frågan är fortfarande snabb, och den yttre sorterar bara några rader (förutsatt att det finns få bilder per produkt), och kan därför fortfarande använda order by rand().




  1. Oracle Lägg till 1 timme i SQL

  2. JDBC ResultSet intern mekanism för att hämta stora datamängder

  3. MySQL rumslig geometri validera wkt

  4. Hur man delar upp Oracle sql-satser för ADO.NET