Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Satunnainen rivi tietokannasta

ZuBer [27.06.2012 11:21:09]

#

Moi!

id |nimi   |luokka
-----------------
1  |mersu  |1
2  |lehmä  |3
3  |derbi  |2
4  |bemari |1
5  |volvo  |1
6  |kissa  |3
7  |banaani|4

Yllä on nyt esimerkkitietokantani. Haluan hakea sieltä jonkun sattumanvaraisen auton. Mutta en osaa. Koko tietokannasta randomin hakeminen onnistuu, mutta jos tietyn arvon pitää olla tietty, menee jo yli. Voisiko joku auttaa?

syyskimo [27.06.2012 12:28:57]

#

SELECT * FROM `mikalietaulu` WHERE `luokka` = '1' ORDER BY RAND() LIMIT 1

Jaska [27.06.2012 12:51:43]

#

Kts. esim. http://stackoverflow.com/questions/19412/how-to-request-a-random-row-in-sql . Siellä on annettu ratkaisu, joka lienee useimmiten nopeampi kuin syyskimon ratkaisu.

syyskimo [27.06.2012 13:12:25]

#

Kyseessä olevassa tapauksessa asialla tehokkuudella lienee ihan sikana merkitystä (not).

Sitä paitsi, tässä tilanteessa ei haeta kaikista riveistä vaan luokalla suodatetuista riveistä, joka aihettaa sen, että on hyvin suuri todennäköisyys että on isoja rakoja kasautunut väleihin, jolloin toiset arvot ovat suuresti todennäköisempiä kuin toiset -> haisee.

Tehostaa toki voi monella tapaa, mutta se että kannattaako, riippuu ihan kannan koo'osta ja muutenkin käyttötarpeesta, mutta mielestäni antamasi linkki on epätoimiva tähän tapaukseen.

Jaska [27.06.2012 13:29:57]

#

Niin, no ajattelin, että kun Zuber antoi esimerkkitietokantansa, niin ehkäpä tuotantotietokanta voi olla paljon isompi.

syyskimo [27.06.2012 14:12:46]

#

Kuinka iso tuotantotietokannan tulisi olla?

Testataanpa:
240 rivistä - kysely kesti 0.0019 sek (order by rand() )
240 rivistä - kysely kesti 0.0008 sek (max-tekniikka)
2304 rivistä - kysely kesti 0.0025 sek (order by rand() )
2304 rivistä - kysely kesti 0.0008 sek (max-tekniikka)
13637 rivistä - kysely kesti 0.0487 sek (order by rand() )
13637 rivistä - kysely kesti 0.0010 sek (max-tekniikka)

Palvelin jolla testasin on tuollainen vanha kehityspalvelimeksi alistettu nuhapumppu.

Toki voisi optimoida, mutta jos tuota linkkaamaasi pätkää soveltaa vaikkapa tuohon esimerkkikantaan (7 riviä), niin todennäköisyysjakauma on:
14% mersu
43% bemari
14% volvo
29% ei yhtään mitään

vs. ORDER BY RAND() 1/7 kaikille + aina tulee tulos

syyskimo [28.06.2012 06:08:00]

#

No kas,

Hienoinen aivopieru päässyt edelliseen viestiini:
ORDER BY RAND() tod näk on tietysti 1/3 jokaiselle, eikä 1/7.

Ja sitten tuota max-tekniikka voi toki korjata, niin että se palauttaa aina jotain laittamalla (SELECT MAX(...) -osioon saman WHERE-lauseen kuin itse hakuun.

Mutta silti tuo (max-tekniikka) tekee filtteröinnin jälkeen epätaisaista jälkeä enkä suosittelisi käyttämään sitä missään rajatussa haussa, enkä varsinkaan tässä kun rajaus on suuri. Mutta ihan söpö tekniikka muuten, varsin oivaltavasti käytetty indeksejä.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta