sql >> Database >  >> RDS >> Mysql

Hoe snel 3 willekeurige records SELECTEREN uit een 30k MySQL-tabel met een waar-filter door een enkele query?

Lelijk, maar snel en willekeurig. Kan erg snel erg lelijk worden, vooral met de hieronder beschreven afstemming, dus zorg ervoor dat je het echt op deze manier wilt.

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

Eerste rij verschijnt vaker dan zou moeten

Als u grote hiaten heeft tussen ID's in uw tabel, hebben rijen direct na dergelijke hiaten een grotere kans om door deze zoekopdracht te worden opgehaald. In sommige gevallen zullen ze significant vaker verschijnen dan zou moeten. Dit kan in het algemeen niet worden opgelost, maar er is een oplossing voor een veelvoorkomend bijzonder geval:wanneer er een gat is tussen 0 en de eerste bestaande ID in een tabel.

In plaats van subquery (SELECT RAND()*<max_id> AS ID) gebruik iets als (SELECT <min_id> + RAND()*(<max_id> - <min_id>) AS ID)

Duplicaten verwijderen

De query, indien gebruikt zoals deze is, kan dubbele rijen retourneren. Het is mogelijk om dat te voorkomen door UNION . te gebruiken in plaats van UNION ALL . Op deze manier worden duplicaten samengevoegd, maar de query garandeert niet langer dat exact 3 rijen worden geretourneerd. Je kunt dat ook omzeilen door meer rijen op te halen dan je nodig hebt en het buitenste resultaat als volgt te beperken:

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

Er is echter nog steeds geen garantie dat 3 rijen worden opgehaald. Het maakt het alleen maar waarschijnlijker.



  1. Basisprincipes van SQL Server ALTER TABLE-instructie

  2. Geavanceerde Oracle JDeveloper-functies gebruiken voor MySQL-databases

  3. 6 manieren om dubbele rijen in SQLite te selecteren

  4. Wat is het verschil tussen het 'yy'- en 'rr'-datummasker van orakel?