Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Consulta SQL lentisima

Estas en el tema de Consulta SQL lentisima en el foro de Mysql en Foros del Web. Buenas noches, soy novatillo en el mundo de la programacion y tambien en MySQL. Tengo una consulta que me esta dando la lata . Lo ...
  #1 (permalink)  
Antiguo 03/12/2007, 16:27
 
Fecha de Ingreso: agosto-2006
Ubicación: Madrid
Mensajes: 16
Antigüedad: 17 años, 7 meses
Puntos: 0
Consulta SQL lentisima

Buenas noches, soy novatillo en el mundo de la programacion y tambien en MySQL.
Tengo una consulta que me esta dando la lata . Lo primero es que no sacaba los resultados (unas estadisticas) de forma totalmente real. Ya si lo hace bien, pero tarda 2 minutos y pico en sacar el resultado. Me han hablado de procedimientos almacenados, pero nose si con eso ganara velocidad, no se como funcionan, las vistas servirian para algo???.....
Tambien se me ha ocurrido que en lugar de que cada vez que se solicite esa consulta saque los datos actuales, a tiempo real, saque datos que ya han sido volcados a una pagina html. Es decir que MySQL un par de veces al dia actualice los datos en una pagina y asi cuando accedan a la consulta, el resultado sera instantaneo, aunque no sea a tiempo real, que les da igual.
Os pongo la consulta. Acepto todo tipo de sugerencias y opiniones al respecto.
Muchas gracias de antemano.

Código:
 
SELECT SQL_CACHE curso, 
titulo, 
SUM((SELECT CASE WHEN (examenes_aprobados=cantidad_examenes) THEN 1 ELSE 0 END)) AS aprobados, 
SUM((SELECT CASE WHEN (examenes_aprobados<>cantidad_examenes) THEN 1 ELSE 0 END)) AS suspensos, 
COUNT(usuario) AS total 
FROM (SELECT tabla_estado_alumnos.usuario AS usuario, 
tabla_estado_alumnos.num_test_aprobados_por_curso AS examenes_aprobados, 
tabla_estado_alumnos.curso AS curso, 
tabla_examenes_curso.numero_examenes AS cantidad_examenes, 
tabla_estado_alumnos.test as titulo 
FROM (SELECT puntuaciones.usr_id as usuario, 
SUM((SELECT CASE WHEN (puntuaciones.puntuacion >= cursos.cur_porcentaje_aprobacion) THEN 1 ELSE 0 END)) as num_test_aprobados_por_curso, 
puntuaciones.cur_id as curso, 
puntuaciones.cur_titulo as test 

FROM cursos, 
(SELECT SQL_CACHE resultado.ale_fecha AS Fecha, 
cursos.cur_id, 
usuarios.usr_id, 
cursos.cur_titulo, 
COUNT(resultado.ale_id) AS Preguntas, 
COUNT(correctas.evr_id) AS Correctas, 
(100.0 / COUNT(resultado.ale_id) )* COUNT(correctas.evr_id) AS Puntuacion, 
usuarios.usp_id 
FROM alumnos_evaluaciones AS resultado 
INNER JOIN usuarios ON (usuarios.usr_id = resultado.usr_id) 
INNER JOIN evaluacion_respuestas AS todas ON (todas.evr_id = resultado.evr_id) 
INNER JOIN evaluacion_preguntas AS p ON (todas.evp_id = p.evp_id) 

INNER JOIN items ON (items.itm_id = p.itm_id) 
INNER JOIN cursos ON (cursos.cur_id = items.cur_id AND cursos.cur_fecha_alta <= NOW() AND ((cursos.cur_fecha_baja IS NULL) OR (cursos.cur_fecha_baja >= NOW() ))) 
LEFT JOIN evaluacion_respuestas AS correctas ON ( correctas.evr_id = resultado.evr_id AND correctas.evr_correcta = 1 ) 
where resultado.ale_fecha IN (select MAX(ale_fecha) from alumnos_evaluaciones al 
where al.usr_id = usuarios.usr_id AND al.cur_id = cursos.cur_id) 
GROUP BY 1,2) AS puntuaciones, 
(SELECT lista_items_alumno.usr_id AS id_usuario, 
lista_items_curso.id_curso AS id_curso 
FROM (SELECT COUNT(itm_id) AS num_items, 
cursos.cur_titulo AS titulo, 
cursos.cur_id AS id_curso 
FROM items, 
cursos 
WHERE (items.cur_id = cursos.cur_id) 
AND (items.tip_id='evaluacion') 
GROUP BY cursos.cur_id) AS lista_items_curso, 
(SELECT items.cur_id, 
COUNT(alumnos_progreso.itm_id) AS num_items_alumno, 
alumnos_progreso.usr_id, 
usuarios.usp_id 
FROM items, 
alumnos_progreso, 
usuarios 
WHERE (items.tip_id='evaluacion') 
AND (items.itm_id=alumnos_progreso.itm_id) 
AND (usuarios.usr_id=alumnos_progreso.usr_id) 
AND usuarios.usr_baja IS NULL 
GROUP BY items.cur_id, 
alumnos_progreso.usr_id, 
usuarios.usp_id) AS lista_items_alumno 
WHERE (lista_items_alumno.num_items_alumno = lista_items_curso.num_items) 
AND (lista_items_curso.id_curso = lista_items_alumno.cur_id) 
GROUP BY 1,2) AS finalizados 
WHERE (cursos.cur_id = puntuaciones.cur_id) 
AND (puntuaciones.cur_id = finalizados.id_curso) 
AND (puntuaciones.usr_id = finalizados.id_usuario) 
GROUP BY 1,3) AS tabla_estado_alumnos, 
(SELECT cursos.cur_id AS curso, 
COUNT(items.cur_id) AS numero_examenes 
FROM cursos, 
items 
WHERE (cursos.cur_id=items.cur_id) 
AND (items.tip_id='evaluacion') 
GROUP BY 1) AS tabla_examenes_curso 
WHERE (tabla_estado_alumnos.curso=tabla_examenes_curso.curso)) AS tabla_final 
GROUP BY curso 
ORDER BY titulo
  #2 (permalink)  
Antiguo 04/12/2007, 09:54
Avatar de cala932  
Fecha de Ingreso: septiembre-2006
Ubicación: San Juan-Argentina
Mensajes: 902
Antigüedad: 17 años, 7 meses
Puntos: 9
Re: Consulta SQL lentisima

Holas, quizas pueda resultarte util este enlace, te lo dejo para que le heches una mirada.
Optimizar consultas
Espero que te sirva.
Saludos
__________________
->Aprender es un proceso que incluye el error..
  #3 (permalink)  
Antiguo 05/12/2007, 09:31
 
Fecha de Ingreso: agosto-2006
Ubicación: Madrid
Mensajes: 16
Antigüedad: 17 años, 7 meses
Puntos: 0
Re: Consulta SQL lentisima

Muchas gracias cala932.
Finalmente, estoy haciendo un cron, para que por las noches me haga esta consulta y guarde los datos en otra tabla. Asi luego es solamente hacer una Select corrientita que tarda muy poco.

Saludo
  #4 (permalink)  
Antiguo 05/12/2007, 09:55
Avatar de maury_indocumentado  
Fecha de Ingreso: noviembre-2007
Mensajes: 29
Antigüedad: 16 años, 5 meses
Puntos: 0
Re: Consulta SQL lentisima

Si me pudieras describir cual seria el resultado que quieres obtener de la consulta y a las tablas a las cuales quieres consultar
te podria ayudar

ok ???

saludos

bye
  #5 (permalink)  
Antiguo 05/12/2007, 11:09
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Re: Consulta SQL lentisima

Estás haciendo varios productos cartesianos en la combinación de tablas. Esto multiplica inmensamente la cantidad de registros resultantes.
haz una serie de subconsultas centrales acotando los datos que necesitas reunir con los campos pivote entre cada subconsulta, y a esas subconsultas, con alias, realizales un inner join escalonado.

Concentrate en resolver el conjunto de datos por partes. Si intentas todo al mismo tiempo no podrás ver dónde se producen los problemas.
Por ejemplo:

1. Los resultados con los usuarios.
2. Las preguntas con las respuestas.
3. Los items con los cursos.

Luego recién el resultado 1 con el 2, y el (1,2) con el 3.

No intentes un INNER JOIN entre seis tablas simultáneamente. Para probar lo que digo, realiza un EXPLAIN de tu consulta y verás cuántos registros y tablas realmente están operando en memoria.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 20:59.