Embora não exista uma "ordem rápida por rand()", existe uma solução alternativa para sua tarefa específica.
Para obter qualquer linha aleatória única , você pode fazer como este blogueiro alemão faz:http://web.archive.org/web/20200211210404/http://www.roberthartung.de/mysql-order-by-rand-a- estudo de caso-de-alternativas/ (Não consegui ver um URL de hotlink. Se alguém vir um, sinta-se à vontade para editar o link.)
O texto está em alemão, mas o código SQL está um pouco abaixo da página e em grandes caixas brancas, então não é difícil de ver.
Basicamente o que ele faz é fazer um procedimento que faz o trabalho de obter uma linha válida. Isso gera um número aleatório entre 0 e max_id, tente buscar uma linha e, se ela não existir, continue até encontrar uma que exista. Ele permite buscar x número de linhas aleatórias armazenando-as em uma tabela temporária, então você provavelmente pode reescrever o procedimento para ser um pouco mais rápido buscando apenas uma linha.
A desvantagem disso é que, se você excluir MUITAS linhas e houver grandes lacunas, as chances são grandes de que ele perca muitas vezes, tornando-o ineficaz.
Atualização:diferentes tempos de execução
Pode ter a ver com indexação.
id
é indexado e rápido de acessar, enquanto adicionar username
para o resultado, significa que ele precisa ler isso de cada linha e colocá-lo na tabela de memória. Com o *
ele também precisa ler tudo na memória, mas não precisa pular o arquivo de dados, o que significa que não há perda de tempo na busca. Isso faz diferença apenas se houver colunas de comprimento variável (varchar/texto), o que significa que ele precisa verificar o comprimento e pular esse comprimento, em vez de apenas pular um comprimento definido (ou 0) entre cada linha.