Il generatore di numeri pseudo-casuali MySQL è completamente deterministico. I documenti dicono:
Non può usare /dev/random perché MySQL è progettato per funzionare su una varietà di sistemi operativi, alcuni dei quali non hanno un /dev/random.
MySQL inizializza un seme predefinito all'avvio del server, utilizzando il numero intero restituito da time(0)
.Se sei interessato alla riga sorgente, è nella sorgente MySQL nel file sql/mysqld.cc, funzione init_server_components()
. Non credo che si rigeneri mai da solo.
Quindi i successivi numeri "casuali" si basano esclusivamente sul seme. Vedi file sorgente mysys_ssl/my_rnd.cc, funzione my_rnd()
.
La soluzione ottimale per l'attività di selezione casuale, sia per le prestazioni che per la qualità della randomizzazione, consiste nel generare un valore casuale tra il valore minimo della chiave primaria e il valore massimo della chiave primaria. Quindi usa quel valore casuale per selezionare una chiave primaria nella tabella:
SELECT ... FROM MyTable WHERE id > $random LIMIT 1
Il motivo per cui useresti> invece di =è che potresti avere degli spazi vuoti nell'id a causa dell'eliminazione o del rollback delle righe, oppure potresti avere altre condizioni nella tua clausola WHERE in modo da avere spazi tra le righe che corrispondono alle tue condizioni .
Gli svantaggi di questo metodo maggiore di:
- Le righe che seguono un tale divario hanno maggiori possibilità di essere scelte e maggiore è il divario maggiore è la possibilità.
- Devi conoscere MIN(id) e MAX(id) prima di generare il valore casuale.
- Non funziona altrettanto bene se hai bisogno di più di una riga casuale.
Vantaggi di questo metodo:
- È molto più veloce di ORDER BY RAND(), anche per tavoli di dimensioni modeste.
- Puoi usare una funzione casuale al di fuori di SQL.