Naključen zapis iz MySQL tabele

1 minute read

Kako izbrati naključen zapis iz MySQL tabele? Kar nekaj rešitev pride na misel, pa so dobre? Zadnjih nekaj dni opazujem nekoga, ki se matra s tem, pa mu nikakor ne uspe tako, da si ne bi preobremenil strežnika. Imena ne bom omenjal, če pa kdo ve, na koga mislim, mu pa lahko pove za tale članek.

Torej, kaj nam prvo pade na pamet za rešitev tega problema? Naslednje seveda:

SELECT * FROM tabela ORDER BY RAND() LIMIT 1;

Zadeva sicer deluje, vendar joj, če imamo v tabeli nekaj tisoč zapisov, se stvari zapletejo. Naš strežnik nas kar naenkrat ne mara, saj mora za pridobitev enega zapisa obdelati kar celo tabelo, za to pa potrebuje kar nekaj časa.

Rešitev je povsem preprosta. Vsak zapis v tabeli imamo, če se seveda držimo nekih osnovnih pravil, označen z unikatno ID številko, to polje je pa seveda tudi naš PRIMARY KEY. Najprej poskusimo ugotoviti, katera je največja ID številka v tabeli. Enostavno:

SELECT MAX(id) FROM TABELA;

Gornjo poizvedbo MySQL kar pridno optimizira in pogleda le ID zadnjega zapisa, torej je obdelava enostavna in hitra. Super, kaj pa sedaj? Predpostavimo, da delamo s PHPjem in da smo rezultat gornje poizvedbe shranili v spremenljivko $maxID.

$randomID = rand(1,$maxID);

V spremenljivko $randomID smo shranili neko naključno vrednost med 1 in $maxID, recimo da je to 3245. Samo še naslednji query:

SELECT * FROM tabela WHERE id = 3245;

In imamo svoj naključni zapis. Hmm, ni tako enostavno, kaj pa če smo kakšen zapis kdaj brisali? Mogoče prav izbrana ID številka v tabeli manjka. Če ne, potem je gornja koda čisto pravilna rešitev, drugače pa takole:

SELECT * FROM tabela WHERE id >= 3245 LIMIT 1;

Tale poizvedba tudi uporabi indeks in zato ni nič počasnejša kot prejšnja.

Poskusite ta sistem na kakšni večji tabeli in primerjajte rezultate. Le-te mi tudi lahko pustite v komentarjih. Moji rezultati na tabeli z 19.000 zapisi:

SELECT * FROM tabela ORDER BY RAND() LIMIT 1;

1 row in set (0.26 sec)

SELECT MAX(id) FROM tabela;

1 row in set (0.00 sec)

SELECT * FROM tabela WHERE id >= 7000 LIMIT 1;

1 row in set (0.00 sec)

Ni prav zanemarljiva razlika, kajne?

Updated: