in

sql – MySQL: alternativas a ORDER BY RAND ()

apple touch icon@2

La solución que estoy usando también se publica en el siguiente enlace: ¿Cómo puedo optimizar la función ORDER BY RAND () de MySQL?

Supongo que su tabla de usuarios será más grande que su tabla de perfiles, si no, entonces es cardinalidad 1 a 1.

Si es así, primero haría una selección aleatoria en la tabla de usuarios antes de unirme a la tabla de perfiles.

Primero haz la selección:

SELECT *
FROM users
WHERE users.ownership = 1 OR users.stamp = 1

Luego, de este grupo, elija filas aleatorias a través de la probabilidad calculada. Si su tabla tiene M filas y desea seleccionar N filas aleatorias, la probabilidad de selección aleatoria debe ser N / M. Por eso:

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 subconsulta que calcula el recuento de filas de la tabla. Sin embargo, dado que estamos trabajando en probabilidad, es posible tener MENOS que $ limitCount de filas devueltas. Por lo tanto, deberíamos multiplicar N por un factor para aumentar el tamaño del grupo 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)

Por lo general, establezco $ factor = 2. Puede establecer el factor en un valor más bajo para reducir aún más el tamaño del grupo aleatorio (por ejemplo, 1,5).

En este punto, ya habríamos limitado una tabla de tamaño M a aproximadamente 2N. 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 consulta ORDER by RAND () normal.

¡Espero que esto ayude!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

quick sort partition animation

Estructura de datos y algoritmos: clasificación rápida

Kn68HvgidEH95WbNvuzP2F 1200 80

Modern Warfare Cheshire Park Easter egg: cómo activar el flautista y hacer explotar las ratas