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

Hvordan vælger man hurtigt 3 tilfældige poster fra en 30k MySQL-tabel med et where-filter efter en enkelt forespørgsel?

Grim, men hurtig og tilfældig. Kan blive meget grim meget hurtigt, især med tuning beskrevet nedenfor, så sørg for at du virkelig vil have det på denne måde.

(SELECT Products.ID, Products.Name FROM Products INNER JOIN (SELECT RAND()*(SELECT MAX(ID) FROM Products) AS ID) AS t ON Products.ID >= t.ID WHERE Products.HasImages=1 ORDER BY Products.ID LIMIT 1) UNION ALL (SELECT Products.ID, Products.Name FROM Products INNER JOIN (SELECT RAND()*(SELECT MAX(ID) FROM Products) AS ID) AS t ON Products.ID >= t.ID WHERE Products.HasImages=1 ORDER BY Products.ID LIMIT 1) UNION ALL (SELECT Products.ID, Products.Name FROM Products INNER JOIN (SELECT RAND()*(SELECT MAX(ID) FROM Products) AS ID) AS t ON Products.ID >= t.ID WHERE Products.HasImages=1 ORDER BY Products.ID LIMIT 1)

Første række vises oftere, end den burde

Hvis du har store mellemrum mellem ID'er i din tabel, vil rækker lige efter sådanne huller have større chance for at blive hentet af denne forespørgsel. I nogle tilfælde vil de optræde betydeligt oftere, end de burde. Dette kan ikke løses generelt, men der er en løsning til et almindeligt tilfælde:når der er et hul mellem 0 og det første eksisterende ID i en tabel.

I stedet for underforespørgsel (SELECT RAND()*<max_id> AS ID) brug noget som (SELECT <min_id> + RAND()*(<max_id> - <min_id>) AS ID)

Fjern dubletter

Forespørgslen, hvis den bruges som den er, kan returnere duplikerede rækker. Det er muligt at undgå det ved at bruge UNION i stedet for UNION ALL . På denne måde vil dubletter blive slået sammen, men forespørgslen garanterer ikke længere at returnere nøjagtigt 3 rækker. Du kan også omgå det ved at hente flere rækker, end du har brug for, og begrænse det ydre resultat på denne måde:

(SELECT ... LIMIT 1)
UNION (SELECT ... LIMIT 1)
UNION (SELECT ... LIMIT 1)
...
UNION (SELECT ... LIMIT 1)
LIMIT 3
 

Der er dog stadig ingen garanti for, at 3 rækker bliver hentet. Det gør det bare mere sandsynligt.



  1. Sådan gemmer du billeder i mysql-database ved hjælp af php

  2. Brug af IN-sætningen med en kommasepareret streng fra outputtet af en replace() funktion i Oracle SQL

  3. Kan ikke hente flere tabelenheder gennem Lagret procedure ved brug af dvale

  4. MySQL - Vælg den sidste indsatte række nemmeste måde