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

Problema Consulta Complicada

Estas en el tema de Problema Consulta Complicada en el foro de Mysql en Foros del Web. Hola a todos, A ver, estoy intentando hacer una consulta complicada. Tengo una tabla, con 2 campos: id, y id_prev. Imaginaos una tabla así: Cita: ...
  #1 (permalink)  
Antiguo 28/03/2007, 18:23
 
Fecha de Ingreso: febrero-2007
Mensajes: 244
Antigüedad: 12 años, 9 meses
Puntos: 0
Problema Consulta Complicada

Hola a todos,

A ver, estoy intentando hacer una consulta complicada. Tengo una tabla, con 2 campos: id, y id_prev.

Imaginaos una tabla así:
Cita:

id id_prev
------------------
1 NULL
2 1
3 2
4 3
5 NULL
6 4
7 5
8 6
9 7
10 8
Lo que quiero sacar es por ejemplo, los id que tengan como id_prev otros id que como id_prev sea NULL (no se si me explico). En el ejemplo, querría sacar 2 y 7.

El caso es que tengo hechas las consultas, pero son muy lentas (ya que hago esto hasta 5 niveles). Os pongo las consultas que yo tengo:

Cita:
SELECT id FROM tabla WHERE id_prev IS NULL

Y ahora por cada registro devuelto, hago:

SELECT id FROM tabla WHERE id_prev=´registrodevuelto´
Esto me va muy lento (ya que como os digo, lo hago hasta 5 niveles). Tenéis alguna idea de como optimizar esto??

Muchas gracias.
  #2 (permalink)  
Antiguo 29/03/2007, 11:23
 
Fecha de Ingreso: enero-2004
Mensajes: 63
Antigüedad: 15 años, 10 meses
Puntos: 0
Re: Problema Consulta Complicada

Esta consulta te servirá:

Código:
SELECT id FROM tabla WHERE id_prev IN(SELECT id FROM tabla WHERE id_prev IS NULL)
Es algo más rápida ya que se obtienen los IDs de segundo nivel en una sola consulta en lugar de una por ID pero no sé si ganarás mucha velocidad. Para obtener el tercer nivel sería cosa de anidar otra subconsulta y así sucesivamente. Revisa qué es exactamente lo que necesita tu aplicación y optimiza según eso. Por ejemplo, si solo necesitas que cada usuario pueda ver cuantos referidos tiene en 5 niveles desde el suyo, haz que el número se almacene en otra tabla (campos: id, nivel, cantidad). Esta tabla se actualizaría cada vez que alguien se dé de alta y sería más eficiente. Pero esto es solo un ejemplo. Eso depende de cómo vaya a funcionar tu aplicación y qué necesidades tengas.

Un saludo
  #3 (permalink)  
Antiguo 29/03/2007, 11:36
 
Fecha de Ingreso: febrero-2007
Mensajes: 244
Antigüedad: 12 años, 9 meses
Puntos: 0
Re: Problema Consulta Complicada

Hola javi_bus!!!

Lo que había probado es esto:

Cita:
SELECT id FROM tabla WHERE id_prev = ANY(SELECT id FROM tabla WHERE id_prev IS NULL)
Es mucho más rápida la verdad, pero hay en ocasiones que al final me dice que tiempo excedido...así que creo que he mejorado mucho pero no se si lo suficiente.
  #4 (permalink)  
Antiguo 29/03/2007, 11:50
 
Fecha de Ingreso: enero-2004
Mensajes: 63
Antigüedad: 15 años, 10 meses
Puntos: 0
Re: Problema Consulta Complicada

Creo que es mejor usar "IN" que "= ANY". De todos modos si dices que te caducan las consultas, creo que eso es un problema. Las consultas deben ser muy rápidas o te tumbarán el servidor en cuanto tengas varios usuarios concurrentes ya que cuando una consulta está trabajando, se bloquean partes de la BD que no pueden ser usadas por las otras consultas hasta que la primera termine.

Yo buscaría otros métodos para optimizar eso. Yo suelo hacer en mis programas muchas cosas de ese tipo para evitar consultas repetitivas o consultas lentas. Por ejemplo uso bastante los procesos cron del servidor para que sea este el que ejecute una serie de consultas complicadas y lentas una vez cada hora, cada día, etc. Estas se ejecutan eliminando la caducidad o dejándola muy alta y asçi no hay problemas porque se ejecutan muy pocas veces. Para otros casos hago cosas como la que te dije: realizar actualizaciones de unos registros que contienes una serie de cálculos que si se hacen en tiempo real son muy lentos. En cambio, si sumas 1 referido a esas cuentas cada vez que alguien se da de alta, el rendimiento aumenta. Con el primer caso no lo tendrás actualizado permanentemente (se actualizará cada vez que se ejecute el cron) y con el otro caso se mantendrá permanentemente actualizado.

Yo miraría un poco eso ya que mejorando esta consulta no vas a poder sacar mejorar mucho eso.

Un saludo
  #5 (permalink)  
Antiguo 29/03/2007, 11:57
 
Fecha de Ingreso: enero-2004
Mensajes: 63
Antigüedad: 15 años, 10 meses
Puntos: 0
Re: Problema Consulta Complicada

Te pongo un ejemplo de lo útiles que son los procesos cron:

Para una aplicación voy a desarrollar un sistema de estadísticas para poder ver tanto el tráfico como las ventas y saber cómo se producen, de donde vienen, etc. Además de las estadísticas, debe guardar un log con información detallada de cada visita recibida en los últimos X días. Es un sistema con muchos cálculos complejos que si se hiciesen en tiempo real, saturarían el servidor enseguida.

La solución: en cada visita solo se hará un insert con la información detallada de la visita. Y una vez al día, a las 3, 4 o 5 de la mañana un proceso cron ejecutará un script php que realizará todos los cálculos de ese día generando las estadísticas. En mi caso no es prioritario tenerlas actualizadas en tiempo real y me vale con una vez cada 24 horas. Eso depende de cada caso. Pero la idea es esa.

Un saludo
  #6 (permalink)  
Antiguo 29/03/2007, 13:55
 
Fecha de Ingreso: febrero-2007
Mensajes: 244
Antigüedad: 12 años, 9 meses
Puntos: 0
Re: Problema Consulta Complicada

Hola javi_bus!!!

Entonces estás trabajando con lo mismo que yo!! Tema de estadísticas y demás. Te digo más en concreto lo que busco. Tengo una aplicación, de la que quiero sacarlas rutas más comunes. En una tabla, tengo las visitas a cada página, y de que página viene (id_pagina, id_pagina_prev) y de ahí quiero sacar, según el número de clicks que me digan (del 1 al 5), las rutas más comunes.....

Por eso quería hacer esa consulta.

También habíamos barajado, que se realizara la consulta por la noche y se almacenara, pero los datos que se consultarían por el día no serían actuales. Aunque tengo que decir, que tampoco se como lanzar ese proceso por la noche....

Por ahora estoy intentando mejorar esa consulta....
  #7 (permalink)  
Antiguo 29/03/2007, 15:27
 
Fecha de Ingreso: enero-2004
Mensajes: 63
Antigüedad: 15 años, 10 meses
Puntos: 0
Re: Problema Consulta Complicada

Es interesante eso de las rutas más comunes para saber cuales son los hábitos de los usuarios.

Pues yo tiraría por la vía de los procesos cron. En mi caso lo haré seguramente ejecutando un script php cada 24 horas (en horas de muy poco tráfico). El problema es que cada día puedes ver los datos hasta el día anterior. En nuestro caso no es problema. Si te vale eso, es lo mejor de cara al rendimiento.

También puedes hacer que se ejecute cada hora con los mismos procesos cron.

Y luego yo lo que voy a hacer es separar una tabla temporal. Me explico: en mi caso el software almacena los datos completos de cada visita en un log que no es más que una tabla temporal. Cuando se ejecuta un proceso cron, este hace los cálculos usando los datos de esa tabla temporal (usando un tope de registros por tiempo para no utilizar los que se añadan con visitas mientras se realiza el proceso). Una vez hechos los cálculos, el proceso cron borra los datos sobrantes de un log mayor que tengo (tiene que almacenar estadísticas detalladas de los últimos X días por si necesitas ver algo), es decir, borra la información caducada de ese log. Después mete los registros del log temporal a esa tabla (usando de nuevo el tope de tiempo para no tocar los nuevos que hayan podido aparecer) y por último se borran los registros de esa tabla temporal con el tope de tiempo (registros ya usados). De este modo, al tener una tabla temporal, los cálculos se hacen sobre una tabla lo más pequeña posible (solo los datos a tratar) y además, si lo ejecutas cada hora, lo bueno es que tendrás menos datos acumulados sobre los que hacer cálculos que si lo ejecutas cada día. Lo malo: que si lo haces cada 24 horas,con hacerlo en horas de poco tráfico no hay problema. Si lo haces cada hora, depende de cuantos registros existan en la tabla temporal, podrá ser "sostenible" en horas puntas o no.

Lo de los procesos cron depende de tu servidor. Tu preocúpate de crear un script php que haga esos cálculos, borre después la tabla temporal (importante esta tabla para hacer cálculos sobre pocos registros, no sobre los acumulados en meses o años) y haz que ese script no tenga caducidad o que este valor sea muy grande. Luego alguien que sepa un poco de servidores, que te programe el servidor para que abra cada x tiempo la url donde se encuentre ese archivo php (ponle un nombre raro con números y letras al azar para que no lo ejecute una persona que "acierte" la url).

A ver si esto te ayuda un poco. En mi caso sirve perfectamente. No he empezado a programarlo y, de hecho, no lo haré hasta al menos dentro de un mes ya que tengo otras cosas que terminar antes. Pero ya lo tengo planeado al milímetro. Eso sí, igual termino añadiéndole algo similar sobre las rutas, como la idea que se te ocurrió, que me parece muy buena.

Si puedo ayudarte en algo más dímelo.

Un saludo
  #8 (permalink)  
Antiguo 29/03/2007, 16:13
 
Fecha de Ingreso: febrero-2007
Mensajes: 244
Antigüedad: 12 años, 9 meses
Puntos: 0
Re: Problema Consulta Complicada

Joer, muchas gracias por la explicación javi_bus. Creo que lo haré así, que lo haga de madrugada, cuando casi nadie accede al servidor. El problema es que me temo que me tocará a mi configurar el servidor y demás. Uso Apache, sabes como podría hacerlo??

Es script, es un script php normal que haga lo que quiera no? Y el servidor será el encargado de lanzarlo a la hora que yo le diga, estoy en lo correcto???

Gracias.
  #9 (permalink)  
Antiguo 29/03/2007, 18:39
 
Fecha de Ingreso: enero-2004
Mensajes: 63
Antigüedad: 15 años, 10 meses
Puntos: 0
Re: Problema Consulta Complicada

Lo que tienes que hacer es programar el cron para que cada x tiempo ejecute un archivo sh. Ese archivo a su vez tiene que contener un comando que abre la url que quieras (la url del archivo php que programes para hacer las tareas del cron).

Es decir, primero preparas un archivo php que al ser ejecutado realice las operaciones. Después, desde la línea de comando creas el archivo elnombrequequieras.sh en tu servidor (por ejemplo en home/root o donde quieras) y lo editas (con vi o con pico) para escribir esto:

Código:
#/bin/sh

wget --spider http://www.dominio.com/archivodelcron.php
Y ya por último falta programar el cron para que ejecute el archivo sh. En mi caso, con el servidor que tenía antes (un Ensim sobre Red Hat) era tan sencillo como meter el archivo sh en un directorio. Tenía los directorios cron.hourly, cron.daily, cron.weekly y cron.monthly. Ahora tengo un servidor con Plesk pero no he mirado aún como va el cron. Mira a ver si tienes estas carpetas. Si no tendrás que hacerlo con el método "tradicional" que consiste en ejecutar el comando "crontab -e", que abre el cron con el editor vi y, creo recordar, que tenías que añadir una línea de este tipo:

Código:
16 11 * * * /home/root/diario.sh
(ejecutaría el archivo sh todos los días a las 16:11).

Código:
59 * * * * /home/root/horario.sh
(ejecutaría el archivo sh todas las horas cuando sean y 59 minutos).

No estoy del todo seguro pero creo que era así.

Un saludo
  #10 (permalink)  
Antiguo 31/03/2007, 10:45
 
Fecha de Ingreso: febrero-2007
Mensajes: 244
Antigüedad: 12 años, 9 meses
Puntos: 0
Re: Problema Consulta Complicada

Hola de nuevo !!!

Estoy haciendo el script que se ejecutará a cierta hora, y lo lanzo para probarlo, pero me lanza este error:

Cita:
Fatal error: Maximum execution time of 30 seconds exceeded in ...
Qué hago para que me termine toda la ejecución??? Sabes porqué puede ser esto ??
  #11 (permalink)  
Antiguo 31/03/2007, 11:12
 
Fecha de Ingreso: enero-2004
Mensajes: 63
Antigüedad: 15 años, 10 meses
Puntos: 0
Re: Problema Consulta Complicada

Holas,

Prueba con esto:

Código:
set_time_limit(0);
Esa instrucción elimina la restricción de tiempo. O puedes simplemente subirlo usando el número de segundos de tiempo máximo en lugar del cero.

Un saludo
  #12 (permalink)  
Antiguo 03/12/2007, 17:40
 
Fecha de Ingreso: agosto-2006
Ubicación: Madrid
Mensajes: 16
Antigüedad: 13 años, 3 meses
Puntos: 0
Re: Problema Consulta Complicada

Hola Vane_ ¿Como acabo el tema? Lo solucionaste??

Javi, como se haria un cron en Windows.

Un saludo

P.D. Javi eres una maquina, y sobre todo como te estiras ayudando a la gente, si todos fueramos iguales.......
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 07:24.