2010-03-31 11 views
6

que es más eficiente (en la gestión de más de 100 mil registros):MySQL vs PHP al recuperar un artículo al azar

A. Mysql

SELECT * FROM user ORDER BY RAND(); 

por supuesto, después de que yo ya tendría todo el campos de ese registro.

B. PHP

uso de memcached para tener $ cache_array contener todos los datos de "SELECT id_user DE ORDEN POR usuario id_user" durante 1 hora o así ... y luego:

$ id = array_rand ($ cache_array);

por supuesto, después de que tengo que hacer una llamada MySQL con:

SELECT * FROM user WHERE id_user = $id; 

así que ... que es más eficiente? A o B?

+0

duplicados: http://stackoverflow.com/questions/1823306/alerternative-to-mysql-order-by-rand –

+2

@OMG los potros: Es similar, pero no una víctima.No está preguntando cuál es la mejor manera de implementarlo en Mysql, está pidiendo una comparación de dos métodos. – ryeguy

+0

De acuerdo con este gráfico (ver el enlace al final), ~ 100K ordenado por RAND() es sub segundo. Tengo curiosidad por ver si PHP (mucho menos .NET o J2EE) proporcionará un rendimiento similar: http://stuff.dasprids.de/images/benchmark-random-row-full.png –

Respuesta

8

La forma correcta de responder a este tipo de pregunta es hacer un punto de referencia. Realice una implementación rápida y sucia en cada sentido y luego ejecute pruebas de referencia para determinar cuál funciona mejor.

Dicho esto, se sabe que ORDER BY RAND() es lento porque es imposible para MySQL usar un índice. MySQL básicamente ejecutará la función RAND() una vez por cada fila en la tabla y luego ordenará las filas en función de lo que regresó de RAND().

Su otra idea de almacenar todos user_id s en memcached y luego seleccionar un elemento aleatorio de la matriz podría funcionar mejor si la sobrecarga de memcached resulta ser menor que el costo de una exploración de tabla completa. Si su conjunto de datos es grande o la caducidad es un problema, puede tener problemas. También está agregando cierta complejidad a su aplicación. Trataría de buscar otra manera.

Le daré una tercera opción que puede superar sus dos sugerencias: Seleccione un count(user_id) de las filas en su tabla de usuario y luego php generará un número aleatorio entre 0 y el resultado de count(user_id) menos 1, inclusive. Luego haz un SELECT * FROM user LIMIT 1 OFFSET random-number-generated-by-php;.

Una vez más, la forma correcta de responder a este tipo de preguntas es hacer una evaluación comparativa. Cualquier otra cosa es especulación.

+0

+1 para la tercera opción –

+0

esto funcionaría muy bien, excepto que olvidé especificar que los registros que se pueden seleccionar deben filtrarse con WHERE flg_pic = 1. Si hago un conteo (id_user) también se considerarán los registros que tienen flg_pic = 0: s – andufo

+0

@andufo: Esto no es realmente un problema en absoluto. Puede hacer 'SELECT COUNT (user_id) FROM user WHERE flg_pic = 1;' y luego 'SELECT * FROM user WHERE flg_pic = 1 LIMIT 1 OFFSET random-number-generated-by-php;'. – Asaph

4

El primero de ellos es increíblemente lento porque

MySQL crea una tabla temporal con todas las filas de resultados y asigna a cada uno de ellos un índice de selección al azar. Los resultados se ordenan y se devuelve .

Se ha elaborado más en this blog post.

0
$random_no = mt_rand(0, $total_record_count); 

$query = "SELECT * FROM user ORDER BY __KEY__ LIMIT {$random_no}, 1";