Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-11-2005
Avatar de AGAG4
AGAG4 AGAG4 is offline
Miembro
 
Registrado: ago 2004
Ubicación: Los Mochis, Sinaloa, México
Posts: 1.420
Poder: 21
AGAG4 Va por buen camino
Optimizar Consulta en Firebird

Tengo un problema con una consulta en Firebird 1.52, tarda como 10 a 15 mins en generarmela y tengo en la tabla sólo 60,000 registros, el objetivo es de extraer aquellos clientes que han dejado de comprar en cierta sucursal en los últimos 4 meses, muestro la sentencia sql:
Código SQL [-]
select s.sucursal,c.cliente,c.nomcli,c.rfccli,
Sum(c.importeant),Sum(c.importe) from TablaVentas c
join tesp_sucursales s on (s.clave = c.sucursal)
where
  c.sucursal = 1 and
  c.cliente >0 and
  ano=2005 and 
  mes >= 1 and 
  mes < 6 and 
  c.cliente not in 
  (select cliente from TablaVentas 
  where 
    ano=2005 and 
    mes >= 6 and cliente = c.cliente) 
group by s.sucursal,c.cliente,c.nomcli,c.rfccli
order by sum(c.importe) desc
*Tengo como PK los campos Sucursal+Cliente+Ano+Mes todos son de tipo Integer.

Realice varias pruebas entre ellas separar el Subselect y ejecutarlo por separado y se ejecutan al instante, pero por lo que veo si son 60,000 registros obviamente realiza 60,000 busquedas en el subselect es por eso el motivo de que tarda una eternidad, en la pc donde hago pruebas es una P4 con 256 MB en RAM y 20GB en Disco Duro, con WinXP Professional SPII.

Alguna sugerencia de optimizarla, se los agradecería muchisimo.

Última edición por AGAG4 fecha: 01-11-2005 a las 19:06:42. Razón: Corrección
Responder Con Cita
  #2  
Antiguo 01-11-2005
Avatar de lpmlpm
lpmlpm lpmlpm is offline
Miembro
 
Registrado: ago 2005
Posts: 136
Poder: 19
lpmlpm Va por buen camino
Asi a ojo, y sin tener las tablas para checar te daría estas sugerencias, trata con esta sentencia modificada:

Código SQL [-]
 select s.sucursal,c.cliente,c.nomcli,c.rfccli,
 Sum(c.importeant),Sum(c.importe) from TablaVentas c
join tesp_sucursales s on (s.clave = c.sucursal)
where
  c.sucursal = 1 and
  c.cliente >0 and
  ano=2005 and 
  mes >= 1 and 
  mes < 6 and 
  c.cliente not in 
  (select cliente from TablaVentas 
   where 
     ano=2005 and 
     mes >= 6) 
group by s.sucursal,c.cliente,c.nomcli,c.rfccli
order by sum(c.importe) desc

Quita la relacion del subselect con la consulta principal para que esta
se ejecute una sola vez, y asi creo que el optimizador interno el va a susutituir
la sentencia in por un exists...al hacer la subconsulta única sin necesidad de iterarla
en cada renglon de la consulta primaria debe hacerlo por lo menos un poco mas rápido...

No se si poniendo el sum que tienes en el order by en el select tambien ganes algo...
__________________
"Lo mejor de no saber hacer nada es que se tiene mucho tiempo libre."
Responder Con Cita
  #3  
Antiguo 02-11-2005
Avatar de AGAG4
AGAG4 AGAG4 is offline
Miembro
 
Registrado: ago 2004
Ubicación: Los Mochis, Sinaloa, México
Posts: 1.420
Poder: 21
AGAG4 Va por buen camino
Nop

Gracias lpmlpm pero no funciono sigue igual no baja de 10 mins. no me quiero imaginar cuando sean 500,000 registros, pero bueno le sigo investigando....

Saludos....

Última edición por AGAG4 fecha: 02-11-2005 a las 01:46:16. Razón: Corrección
Responder Con Cita
  #4  
Antiguo 02-11-2005
Avatar de Zeta
Zeta Zeta is offline
Miembro
 
Registrado: feb 2005
Posts: 215
Poder: 20
Zeta Va por buen camino
Usás índices?

mejoran mucho la velocidad
__________________
And I'd like an hour on the holodeck with Seven of Nine.
Responder Con Cita
  #5  
Antiguo 02-11-2005
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.022
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
¿Puedes pasarnos el metadata de la estructura de la base de datos?, así podemos hacer pruebas nosotros.
Responder Con Cita
  #6  
Antiguo 02-11-2005
Avatar de kalimero
kalimero kalimero is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 288
Poder: 21
kalimero Va por buen camino
Hola.

Bueno sin saber como está estructurada la BD te diria que: si solo te interesa saber si ha comprado o no, mira a ver si puedes agrupar por cliente en la subconsulta. Te evitarás así un monton de registros.

saludos
Responder Con Cita
  #7  
Antiguo 03-11-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
que tal si probas con:

Código SQL [-]
select s.sucursal,c.cliente,c.nomcli,c.rfccli,
       Sum(c.importeant),Sum(c.importe),
       max(c.fecha) MesUltimaCompra
  from TablaVentas c
       inner join tesp_sucursales s on (s.clave = c.sucursal)
 where c.sucursal = 1
   and c.cliente >0
 group by s.sucursal, c.cliente, c.nombli, c.rfccli
having max(c.fecha) < '2005-06-01'

No lo he comprobado, pero debiera mostrarte todos aquellos clientes que no han comprado desde el 1/6/2005.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #8  
Antiguo 04-11-2005
Avatar de AGAG4
AGAG4 AGAG4 is offline
Miembro
 
Registrado: ago 2004
Ubicación: Los Mochis, Sinaloa, México
Posts: 1.420
Poder: 21
AGAG4 Va por buen camino
ok

Si tengo 1 indice por Sucursal+Cliente+Ano+Mes, tome estos campos por ser los que dependen después de la instrucción WHERE de los Select's, pero no aumento mucho la velocidad, voy a probar como me comenta jachguate .

Muchas Gracias....

Última edición por AGAG4 fecha: 04-11-2005 a las 03:47:46. Razón: Corrección
Responder Con Cita
  #9  
Antiguo 04-01-2006
Avatar de AGAG4
AGAG4 AGAG4 is offline
Miembro
 
Registrado: ago 2004
Ubicación: Los Mochis, Sinaloa, México
Posts: 1.420
Poder: 21
AGAG4 Va por buen camino
????

Disculpe la tardanza para verificar las pruebas, revise el Select usando Having funciono Bien, pero tengo el problema de que me obliga agrupar por FECHA y me pone 1 mismo cliente varias veces, por lo que lo que yo quiero es agrupar Sólo por clientes, pero si quito dentro del select el Max(c.fecha) no me serviría el having.

Otra cosa que me di cuenta, si pongo lo siguiente:
Código SQL [-]
....
group by cliente,nomcli,rfccli,fecha
having max(fecha)<'01.08.2005'
order by sum(importe) DESC
No me hace el Ordenamiento Descendente, me pone registros revueltos, Ejemplo:
Importe
1200
1000
800
5000
40000
....

Gracias por su sugerencia.

Última edición por AGAG4 fecha: 04-01-2006 a las 18:32:01.
Responder Con Cita
  #10  
Antiguo 04-01-2006
Avatar de kalimero
kalimero kalimero is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 288
Poder: 21
kalimero Va por buen camino
Hola.
Pues entonces agrega la condicion de la fecha en la clausula WHERE
Saludos
Responder Con Cita
  #11  
Antiguo 04-01-2006
Avatar de AGAG4
AGAG4 AGAG4 is offline
Miembro
 
Registrado: ago 2004
Ubicación: Los Mochis, Sinaloa, México
Posts: 1.420
Poder: 21
AGAG4 Va por buen camino
????

No puedo agregar dentro del where max(fecha)<'01.08.2005' por si no haz leido quiero aquellos clientes que dejaron de comprar en determinada fecha.

ó Si agrego fecha <='01.08.2005' me obliga a poner un Subselect como arriba lo menciono.

Gracias por su respuesta.
Responder Con Cita
  #12  
Antiguo 04-01-2006
Avatar de kalimero
kalimero kalimero is offline
Miembro
 
Registrado: may 2003
Ubicación: Alicante
Posts: 288
Poder: 21
kalimero Va por buen camino
Hola.
No se si entiendo bien lo que dices. Yo me referia a esto.

Código SQL [-]
select s.sucursal,c.cliente,c.nomcli,c.rfccli,
       Sum(c.importeant),Sum(c.importe)
  from TablaVentas c
       inner join tesp_sucursales s on (s.clave = c.sucursal)
 where c.sucursal = 1 and c.fecha < '2005-06-01'
   and c.cliente >0
 group by s.sucursal, c.cliente, c.nombli, c.rfccli

Saludos
Responder Con Cita
  #13  
Antiguo 04-01-2006
Avatar de AGAG4
AGAG4 AGAG4 is offline
Miembro
 
Registrado: ago 2004
Ubicación: Los Mochis, Sinaloa, México
Posts: 1.420
Poder: 21
AGAG4 Va por buen camino
????

A como explicas sólo formas un Grupo de clientes que compraron de Enero a Mayo, pero te falta agregar los clientes que compraron de Junio a Diciembre y Sacar el Grupo Final que Compraron de Enero a Mayo pero que NO ESTEN en el Grupo Junio a Diciembre.
No me sirve saber aquellos clientes que SOLO compraron de Enero a Julio.

Espero haberme explicado.

Saludos....
Responder Con Cita
  #14  
Antiguo 05-01-2006
Avatar de AGAG4
AGAG4 AGAG4 is offline
Miembro
 
Registrado: ago 2004
Ubicación: Los Mochis, Sinaloa, México
Posts: 1.420
Poder: 21
AGAG4 Va por buen camino
Resuelto....

Hasta ahorita me di cuenta que el Having no es dependiente del Group By por lo tanto quite dentro del Select, Max(c.Fecha) y ya me dio los datos correctos.

Gracias a todos....

Feliz Año 2006.
Responder Con Cita
  #15  
Antiguo 10-01-2006
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Lamento entrar hasta ahora y darme cuenta de esto, que ya estaba implicito en la respuesta que te dí hace varios días. Me alegro que todo saliera bien
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 15:54:31.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi