Mysql – losowe rekordy z użyciem order by rand()

Jakiś czas temu napisałem jak uzyskać losowe rekordy bez użycia order by rand(). Niestety nie zawsze daje się to uzyskać i pojawia się w takim momencie problem wielkości danych. Im więcej złączeń dodających kolumny do zestawu wyników tym gorzej dla nas. Chyba, że odpowiednio podejdziemy do zagadnienia.

Pierwsza i najważniejsza rzecz to działanie jak na najmniejszym zestawie danych. Najłatwiej będzie to przedstawić na przykładzie. Powiedzmy, że chcemy mieć wylosowane artykuły oznaczone jako promowane. Pierwszą rzeczą jaką należy zrobić, to wydzielić informację o promowaniu do osobnej tabeli. Dzięki temu tabela artykułów będzie szczuplejsza (niby bit/bool/tinyint niewiele zajmuje, ale przy dużej liczbie rekordów zaczyna robić ogromne znaczenie). Uzyskamy także odpowiedni zbiór danych, które będzie można posortować losowo bez obaw o bazę danych. Promowanych artykułów będzie niewiele (w porównaniu z całą resztą), wiec spokojnie będziemy mogli wywołać zapytanie:


select art_id from artykuly_promowane order by rand() limit 2

i przekazać uzyskane art_id do zapytania pobierającego dane z tabeli artykułów. Samo pobieranie listy promowanych artykułów będzie wyglądać następująco:


select a.* from artykuly as a inner join artykuly_promowane as ap on ap.art_id = a.id

Należy się tylko upewnić czy art_id jest oznaczone jako klucz unique. Dzięki temu nie pojawią się nadmiarowe rekordy, a dodatkowo mysql będzie w stanie szybko złączyć rekordy.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

*