Generator liczb pseudolosowych MySQL jest całkowicie deterministyczny. Dokumenty mówią:
Nie może używać /dev/random, ponieważ MySQL jest zaprojektowany do pracy na różnych systemach operacyjnych, z których niektóre nie mają /dev/random.
MySQL inicjalizuje domyślny seed podczas uruchamiania serwera, używając liczby całkowitej zwracanej przez time(0)
.Jeśli jesteś zainteresowany wierszem źródłowym, znajduje się on w źródle MySQL w pliku sql/mysqld.cc, funkcja init_server_components()
. Nie sądzę, żeby kiedykolwiek ponownie się zasiał.
Następnie kolejne „losowe” liczby są oparte wyłącznie na nasionach. Zobacz plik źródłowy mysys_ssl/my_rnd.cc, funkcja my_rnd()
.
Najlepszym rozwiązaniem zadania losowego wyboru, zarówno pod względem wydajności, jak i jakości randomizacji, jest wygenerowanie wartości losowej między minimalną wartością klucza podstawowego a maksymalną wartością klucza podstawowego. Następnie użyj tej losowej wartości, aby wybrać klucz podstawowy w tabeli:
SELECT ... FROM MyTable WHERE id > $random LIMIT 1
Powodem, dla którego używasz> zamiast =, jest to, że możesz mieć przerwy w identyfikatorze z powodu usunięcia lub wycofania wierszy lub możesz mieć inne warunki w klauzuli WHERE, aby mieć przerwy między wierszami, które pasują do twoich warunków .
Wady tej metody „większego niż”:
- Rzędy następujące po takiej przerwie mają większą szansę na wybór, a im większa przerwa, tym większa szansa.
- Musisz znać MIN(id) i MAX(id) przed wygenerowaniem wartości losowej.
- Nie działa tak dobrze, jeśli potrzebujesz więcej niż jednego losowego wiersza.
Zalety tej metody:
- Jest znacznie szybszy niż ORDER BY RAND(), nawet przy niewielkim rozmiarze tabeli.
- Możesz użyć funkcji losowej poza SQL.