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

MySQL:Alternativer til ORDER BY RAND()

OPDATERING 2016

Denne løsning fungerer bedst ved at bruge en indekseret kolonne .

Her er et simpelt eksempel på og optimeret forespørgselsbænk markeret med 100.000 rækker.

OPTIMERET:300 ms

SELECT g.* FROM table g JOIN (SELECT id FROM table WHERE RAND() < (SELECT ((4 / COUNT(*)) * 10) FROM table) ORDER BY RAND() LIMIT 4) AS z ON z.id= g.id

notat om grænsebeløb :grænse 4 og 4/tæller (*). 4'erne skal være det samme tal. At ændre hvor mange du returnerer påvirker ikke hastigheden så meget. Benchmark ved grænse 4 og grænse 1000 er de samme. Begræns 10.000 tog det op til 600 ms

note om deltagelse :At randomisere kun id'et er hurtigere end at randomisere en hel række. Da den skal kopiere hele rækken ind i hukommelsen, så randomiser den. Sammenkædningen kan være en hvilken som helst tabel, der er knyttet til underforespørgslen. Det er for at forhindre tabelscanninger.

bemærk hvor-klausulen :Hvor-tællingen begrænser mængden af ​​resultater, der randomiseres. Det tager en procentdel af resultaterne og sorterer dem i stedet for hele tabellen.

bemærk underforespørgsel :If doing joins og ekstra hvor klausulbetingelser skal du sætte dem både i underforespørgslen og underforespørgslen. At have en nøjagtig optælling og trække korrekte data tilbage.

UOPTIMERET:1200ms

SELECT 
    g.*
FROM
    table g
ORDER BY RAND()
LIMIT 4
 

PROS

4x hurtigere end order by rand() . Denne løsning kan fungere med enhver tabel med en indekseret kolonne.

MINDER

Det er lidt komplekst med komplekse forespørgsler. Skal vedligeholde 2 kodebaser i underforespørgslerne



  1. Hvad er en flad fildatabase? Hvordan adskiller det sig fra en relationel database?

  2. Forskellen mellem WITH-klausul og underforespørgsel?

  3. ORA-04091:tabel [blah] muterer, trigger/funktion kan muligvis ikke se den

  4. MySQL-fejl::'Adgang nægtet for brugeren 'root'@'localhost'