För att illustrera lite hur pass dåliga de dåliga lösningarna faktiskt är. Kört med 7 miljoner ca 100-150 byte rader i en InnoDB tabell på en medelmåttig hårdvara, med en kraftig maskin kan man förvänta sig 20-50% av exekveringstiden:
Exekveringstid ca 15s.
Kod:
SELECT * FROM table ORDER BY RAND() LIMIT 1
Exekveringstid ca 15s. Detta ger inga random-rader men används i vissa, riktigt dåliga, alternativ till ORDER BY RAND().
Kod:
SELECT count(*) FROM table
Exekveringstid 0.02s. Kräver primary key (behöver inte heta id). Ger sämre resultat med större gaps i PK. Måste köras en gång per rad för hyfsad randomness (även om det givetvis går att kombinera i en query). Kan ge kopior varpå man måste ha kod för att hämta fler frågor om man får kopior. För många rader kan det effektiviseras ordentligt genom att lyfta ut id-generation (antingen i en stored procedure eller i kod).
Kod:
SELECT *
FROM table
WHERE id >= FLOOR(1 + RAND() * (SELECT MAX(id) FROM table))
LIMIT 1
Detta är inte de enda alternativen utan bara en illustration till hur enorm skillnad det gör. Problemet med att använda ORDER BY RAND() ligger inte i hur pass exakt RAND() är utan hur pass fruktansvärd prestandan är vid ORDER BY RAND() på något annat än ett VÄLDIGT litet resultset.