R
RTR0N
Beta
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Amigos de Forobeta, después de horas de lectura, escribir mucho código y hacer muchos benchmarks vengo a consultarles lo siguiente:
Resulta que tengo 3 tablas, las cuales son más o menos así:

La aplicación debe en primer lugar mostrar información sobre el video que se esta visualizando (datos como título del video, su descripción, fecha en que fué subido, etc), los tags con los que fué etiquetado y finalmente mostrar un listado de 20 videos relacionados.
Para lo primero hice una consulta simple donde busco el registro en la tabla tp_videos a partir de un código. Mi consulta es esta:
Con eso obtengo el ID y demás datos del video en cuestión.
La siguiente consulta que hago es para mostrar las etiquetas/categorias a las que pertenece el video. La consulta es:
Eso me devuelve el listado de categorias con las que fué etiquedado el video.
Hasta ahí ningún problema, las 2 consultas van como el rayo.
Mi siguiente consulta es para mostrar un listado con 20 videos relacionados de forma aleatoria. Lo resolví con 2 consultas:
Aquí en %s va el listado de los cat_id que he recuperado en la consulta anterior y %d es la cantidad de videos relacionados.
Y finalmente en esta consulta recupero la información de los videos a partir de los vid_id que ha devuelto la consulta anterior.
Cabe mencionar que todo lo anterior lo he resuelto de distintas formas, pero a pesar de que esta última forma son 4 consultas es la que me va más rápido.
EL PROBLEMA básicamente esta con el ORDER BY RAND() de la penúltima consulta, hace que el servidor se ponga muy lento y eso es lo que trato de evitar y tener la consulta lo más optimizado posible para que mi aplicación pueda soportar la máxima cantidad de usuarios al mismo tiempo y de ser posible soportar algunos ataques de niños rata que nunca faltan en la red.
Si alguien pudiera darme una mano para optimizar esa consulta o tiene alguna idea mejor le estaría muy agradecido. No quiero que el servidor explote :/
Haciendo pruebas de rendimiento, ejecutar esas consultas 1000 veces le demora al servidor lo siguientes:
- Sólo la primera consulta: 0.35 seg de media.
- Las 2 primeras consultas : 0.65 seg de media.
- Las 4 consultas: 31 seg. de media :ambivalence:
- Las 4 consultas sin el ORDER BY RAND(): 1.45seg de media:
Como podrán ver el ordenamiento aleatorio hace que la consulta se demore en promedio 20 veces más, pero es muy importante que los videos relacionados se muestren de forma aleatoria o de lo contrario siempre serian los mismos y así no va.
Si no resuelvo esto pronto me volveré loco o voy a morir, ya van toda la noche leyendo (ahora son 05:30am) y ninguna forma de resolverlo :sleeping:
Mi servidor de pruebas es un Core 2 duo E8400.
Resulta que tengo 3 tablas, las cuales son más o menos así:
Insertar CODE, HTML o PHP:
tp_categorias
-cat_id
-cat_titulo
tp_videos
-vid_id
-vid_titulo
tp_videos_categorias
-vid_id
-cat_id

- La relación entre tp_videos y tp_categorias es de muchos a muchos (adjunto captura).
- La tabla tp_categorias almacena informacion sobre las categorias para etiquetar un video.
- La tabla tp_videos almacena información del video como título, descripción, etc.
- La tabla tp_videos_categorias obviamente la relación entre estas 2 tablas.
La aplicación debe en primer lugar mostrar información sobre el video que se esta visualizando (datos como título del video, su descripción, fecha en que fué subido, etc), los tags con los que fué etiquetado y finalmente mostrar un listado de 20 videos relacionados.
Para lo primero hice una consulta simple donde busco el registro en la tabla tp_videos a partir de un código. Mi consulta es esta:
Insertar CODE, HTML o PHP:
SELECT v.vid_id, v.vid_titulo
FROM tp_videos v
WHERE v.vid_codigo = '%s'
LIMIT 1
Con eso obtengo el ID y demás datos del video en cuestión.
La siguiente consulta que hago es para mostrar las etiquetas/categorias a las que pertenece el video. La consulta es:
Insertar CODE, HTML o PHP:
SELECT c.cat_id, c.cat_titulo
FROM tp_categorias c
WHERE c.cat_id IN (
[INDENT]SELECT vc.cat_id
FROM tp_videos_categorias vc
WHERE vc.vid_id = %d[/INDENT]
)
Eso me devuelve el listado de categorias con las que fué etiquedado el video.
Hasta ahí ningún problema, las 2 consultas van como el rayo.
Mi siguiente consulta es para mostrar un listado con 20 videos relacionados de forma aleatoria. Lo resolví con 2 consultas:
Insertar CODE, HTML o PHP:
SELECT vc.vid_id id
FROM tp_videos_categorias vc
WHERE vc.cat_id IN (%s)
ORDER BY RAND()
LIMIT %d
Insertar CODE, HTML o PHP:
SELECT v.vid_id, v.vid_titulo
FROM tp_videos v
WHERE v.vid_id IN (%s)
Cabe mencionar que todo lo anterior lo he resuelto de distintas formas, pero a pesar de que esta última forma son 4 consultas es la que me va más rápido.
EL PROBLEMA básicamente esta con el ORDER BY RAND() de la penúltima consulta, hace que el servidor se ponga muy lento y eso es lo que trato de evitar y tener la consulta lo más optimizado posible para que mi aplicación pueda soportar la máxima cantidad de usuarios al mismo tiempo y de ser posible soportar algunos ataques de niños rata que nunca faltan en la red.
Si alguien pudiera darme una mano para optimizar esa consulta o tiene alguna idea mejor le estaría muy agradecido. No quiero que el servidor explote :/
Haciendo pruebas de rendimiento, ejecutar esas consultas 1000 veces le demora al servidor lo siguientes:
- Sólo la primera consulta: 0.35 seg de media.
- Las 2 primeras consultas : 0.65 seg de media.
- Las 4 consultas: 31 seg. de media :ambivalence:
- Las 4 consultas sin el ORDER BY RAND(): 1.45seg de media:
Como podrán ver el ordenamiento aleatorio hace que la consulta se demore en promedio 20 veces más, pero es muy importante que los videos relacionados se muestren de forma aleatoria o de lo contrario siempre serian los mismos y así no va.
Si no resuelvo esto pronto me volveré loco o voy a morir, ya van toda la noche leyendo (ahora son 05:30am) y ninguna forma de resolverlo :sleeping:
Mi servidor de pruebas es un Core 2 duo E8400.