¿Cómo se puede optimizar el operador ORDER BY RAND()?
sobes.tech AI
Respuesta de la IA
Optimizar ORDER BY RAND() es difícil, ya que requiere una selección completa de datos para generar un número aleatorio para cada fila. Los enfoques típicos:
-
Selección de un identificador aleatorio:
- Obtener el número de filas en la tabla.
- Generar un número aleatorio entre 0 y N-1 (o 1 y N).
- Seleccionar la fila con el desplazamiento correspondiente o
OFFSET.
SELECT COUNT(*) FROM your_table; -- Se asume que el total de filas = N SELECT * FROM your_table LIMIT 1 OFFSET floor(random() * N);Este método es adecuado para seleccionar una o unas pocas filas aleatorias. No es eficiente para un gran número de filas.
-
Selección aleatoria por rango de
id:- Encontrar el
idmínimo y máximo. - Generar un número aleatorio en ese rango.
- Seleccionar la fila con
id >= número_aleatorio, usandoLIMIT.
SELECT MIN(id), MAX(id) FROM your_table; -- Se asume que se obtuvieron min_id, max_id -- En la aplicación, generar un id aleatorio en el rango [min_id, max_id] -- Por ejemplo: id_aleatorio = min_id + floor(random() * (max_id - min_id + 1)) SELECT * FROM your_table WHERE id >= id_aleatorio LIMIT 1;Puede omitir filas si hay huecos en
id. - Encontrar el
-
Creación de una tabla temporal o uso de subconsulta con ordenamiento por número aleatorio:
- Seleccionar un subconjunto de datos o solo
iden una subconsulta. - Aplicar
ORDER BY RAND()a este subconjunto.
SELECT * FROM your_table AS t1 JOIN (SELECT id FROM your_table ORDER BY RAND() LIMIT 100) AS t2 ON t1.id = t2.id;Reduce la carga si
LIMITse aplica a la subconsulta. - Seleccionar un subconjunto de datos o solo
-
Uso de un campo adicional con número aleatorio:
- Añadir un campo en la tabla para almacenar un número aleatorio.
- Actualizar periódicamente este campo para todas las filas.
- Ordenar por este campo.
-- Añadir campo ALTER TABLE your_table ADD random_sort_key FLOAT; -- Actualización periódica UPDATE your_table SET random_sort_key = RAND(); -- Selección SELECT * FROM your_table ORDER BY random_sort_key LIMIT 10;Requiere cambios en el esquema y en el proceso de actualización en segundo plano.
-
Algoritmo de "barajado" (Fisher-Yates) fuera de la base de datos:
- Seleccionar todos los
id(o todos los datos si son pequeños). - Barajar la lista en la aplicación.
- Seleccionar los primeros N elementos.
// Se asume que ids es []int // ids = ... // Obtener ids de la base de datos rand.Shuffle(len(ids), func(i, j int) { ids[i], ids[j] = ids[j], ids[i] }) // Ahora los primeros N elementos de ids son aleatorios // Se pueden usar para seleccionar filas completas // SELECT * FROM your_table WHERE id IN (...)Solo adecuado para tablas con pocas filas.
- Seleccionar todos los
La elección del método óptimo depende del tamaño de la tabla, la cantidad de filas aleatorias requeridas y el sistema de gestión de bases de datos específico. Para la mayoría de los casos, cuando se necesita seleccionar unas pocas filas aleatorias de una tabla grande, la combinación de obtener los id y luego usar OFFSET o WHERE id IN (...) será más eficiente que ordenar por RAND() directamente.