La solución que estoy usando también se puede encontrar en el siguiente enlace: How can i optimize MySQL's ORDER BY RAND() function?
Estoy asumiendo que su tabla de usuarios va a ser más grande que la tabla de perfiles, si no es así, es de 1 a 1 cardinalidad.
Si es así, primero haría una selección aleatoria en la tabla de usuarios antes de unirme a la tabla de perfiles.
En primer lugar hacer la selección:
SELECT *
FROM users
WHERE users.ownership = 1 OR users.stamp = 1
Luego de este grupo, escoger al azar a través de las filas probabilidad calculada. Si su tabla tiene M filas y desea seleccionar N filas al azar, la probabilidad de selección al azar debe ser N/M. Por lo tanto:
SELECT *
FROM
(
SELECT *
FROM users
WHERE users.ownership = 1 OR users.stamp = 1
) as U
WHERE
rand() <= $limitCount/(SELECT count(*) FROM users WHERE users.ownership = 1 OR users.stamp = 1)
Donde N es $ limitCount y M es la sub consulta que calcula el número de fila de la tabla. Sin embargo, dado que estamos trabajando en la probabilidad, es posible tener MENOS de $ limitCount de filas devueltas. Por lo tanto, debemos multiplicar N por un factor para aumentar el tamaño del conjunto aleatorio.
es decir:
SELECT*
FROM
(
SELECT *
FROM users
WHERE users.ownership = 1 OR users.stamp = 1
) as U
WHERE
rand() <= $limitCount * $factor/(SELECT count(*) FROM users WHERE users.ownership = 1 OR users.stamp = 1)
lo general conjunto $ = factor de 2. Se puede establecer el factor a un valor más bajo para reducir aún más el tamaño de la piscina al azar (por ejemplo 1,5).
En este punto, ya habríamos limitado una tabla de tamaño M hasta aproximadamente 2N de tamaño. Desde aquí podemos hacer un JOIN y luego LIMIT.
SELECT *
FROM
(
SELECT *
FROM
(
SELECT *
FROM users
WHERE users.ownership = 1 OR users.stamp = 1
) as U
WHERE
rand() <= $limitCount * $factor/(SELECT count(*) FROM users WHERE users.ownership = 1 OR users.stamp = 1)
) as randUser
JOIN profiles
ON randUser.id = profiles.memberid AND profiles.photo != ''
LIMIT $limitCount
En una tabla grande, esta consulta superará a una ORDEN normal por consulta RAND().
Espero que esto ayude!
No entiendo lo que estás buscando. ¿Por qué no es adecuado 'ORDER BY RAND()'? ¿Le preocupa principalmente la eficiencia? – outis
Sí, eso es correcto. No he llegado ni siquiera cerca de la escala presentada en su gráfico y ya estaba recibiendo un golpe. – Tony
@outis: Como no escala, consulte: http://www.dasprids.de/blog/2008/06/07/fetching-random-rows-of-mysql-efficiently –