Gyorsabb véletlen rekordok lekérdezése

Bizonyára sokszor találkozunk azzal a feladattal, ami arról szól hogyan tudunk kiválasztani 1 véletlen rekordot egy megadott táblából? Pl: egy webáruház megadott rendeléseiből akarunk véletlenszerűen kiválasztani egyet. Ilyenkor a legkézenfekvőbb megoldás lehet erre MySql adatbázist felhasználva a következő lekérdezés:

SELECT * FROM test ORDER BY RAND() LIMIT 0,1;

Sokszor láttam, ezt a kódot nagynevű oldalak sorai között. Vizsgáljuk egy kicsit meg közelebbről. Készítettem egy 500 ezres nagyságrendű adattáblát. Erre egy tesztadatokat készítő egyszerű tárolt eljárást írtam, majd egy teszt osztályt, ami végrehajtja a lekérdezést és kiírja a script futási idejét.

A tesztosztály részeként írtam egy másik lekérdezést, ami ugyanezt végzi el, csak egy kicsit másképp, két lekérdezést futtatva.

SELECT FLOOR(RAND() * COUNT(*)) AS offset FROM test;
SELECT * FROM test LIMIT offset, 1;

A tesztkörnyezetemben az első lekérdezés majdnem 3x olyan lassan fut le, mint a második változat. Az eredmény pedig ugyanaz. Mi lehet ennek az oka?

A magyarázatot a MySql kézikönyvben találhatjuk. Vagyis az első esetben egy segédtábla keletkezik, amit véletlenszerűen rendez, majd ebből visszaadja az elsőt. Az eredmény tehát egy véletlen rekord lesz.

A második esetben, pedig előállít egy véletlen offsetet, a test rekordok számából, majd visszaad a vélelenszámú offsettől 1 darabot, tehát nem történik rendezés és köztes tábla létrehozás.

Egyes esetekben jelentős sebességnövekedést és erőforrás kihasználást tudunk elérni, ha odafigyelünk erre.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter


A bejegyzés kategóriája:Programozás and tagged . Vedd fel a kedvencek közé: link. Szólj hozzá vagy hagyj egy trackback-et:Trackback URL.

Szólj hozzá

Hozzászólás küldéséhez Be kell jelentkezni