ATUALIZAÇÃO 2016
Esta solução funciona melhor usando uma coluna indexada .
Aqui está um exemplo simples de um banco de consultas otimizado marcado com 100.000 linhas.
OTIMIZADO:300 ms
SELECT
g.*
FROM
table g
JOIN
(SELECT
id
FROM
table
WHERE
RAND() < (SELECT
((4 / COUNT(*)) * 10)
FROM
table)
ORDER BY RAND()
LIMIT 4) AS z ON z.id= g.id
observação sobre o valor limite :limite 4 e 4/conta(*). Os 4s precisam ser o mesmo número. Alterar quantos você retorna não afeta muito a velocidade. O benchmark no limite 4 e no limite 1000 são os mesmos. Limite de 10.000 levou até 600ms
observação sobre participação :Randomizar apenas o id é mais rápido do que randomizar uma linha inteira. Como ele precisa copiar a linha inteira para a memória, aleatorize-a. A junção pode ser qualquer tabela que esteja vinculada à subconsulta Its para evitar tablecans.
observe cláusula where :a contagem de where limita a quantidade de resultados que estão sendo randomizados. Ele pega uma porcentagem dos resultados e os classifica em vez de toda a tabela.
observe a subconsulta :As condições da cláusula if fazendo joins e extra where você precisa colocá-las na subconsulta e na subsubconsulta. Para ter uma contagem precisa e recuperar os dados corretos.
NÃO OTIMIZADO:1200 ms
SELECT
g.*
FROM
table g
ORDER BY RAND()
LIMIT 4
PRÓS
4x mais rápido que
order by rand()
. Esta solução pode funcionar com qualquer tabela com uma coluna indexada. CONS
É um pouco complexo com consultas complexas. Necessidade de manter 2 bases de código nas subconsultas