Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Otimizando a consulta ORDER BY RAND() lenta


ORDER BY RAND() é lento porque o DBMS tem que ler todas as linhas, ordenar todas, apenas para manter apenas algumas linhas. Portanto, o desempenho dessa consulta depende muito do número de linhas na tabela e diminui à medida que o número de linhas aumenta.

Não há como otimizar isso.

Existem alternativas, no entanto:

Você pode implementar "obter 5 linhas aleatórias" fazendo 6 consultas:
  • obtenha o número de linhas na tabela (você pode armazenar esta em cache)

  • faça 5 consultas com OFFSET <random offset from 0 to $number_of_rows-1> LIMIT 1 (ou seja, ler e retornar apenas uma linha de algum deslocamento aleatório)

    Por exemplo:SELECT * FROM Products OFFSET 42 LIMIT 1 (nota:sem aderir, por enquanto)

    Tais consultas são muito rápidas e executadas em um tempo praticamente independente do tamanho da tabela.

Isso deve ser muito mais rápido que ORDER BY RAND() .

Agora, para obter uma imagem aleatória para cada produto aleatório:
SELECT *
FROM (
    SELECT *
    FROM Products
    OFFSET 42 LIMIT 1
) p
JOIN ProductImages pi
ON   pi.product_id = p.id
ORDER BY RAND()
LIMIT 1

A consulta interna ainda é rápida e a externa está classificando apenas algumas linhas (supondo que haja poucas imagens por produto) e, portanto, ainda pode usar a ordem por rand().