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

Drama con SUM( multiplicación) a la vez

Estas en el tema de Drama con SUM( multiplicación) a la vez en el foro de Mysql en Foros del Web. Hola todos, estoy trabajando en una empresa que se dedica ala comercialización de productos, Tiene un sistema que trabaja en Linux con PHP y MySql.. ...
  #1 (permalink)  
Antiguo 03/07/2011, 13:36
 
Fecha de Ingreso: noviembre-2007
Mensajes: 66
Antigüedad: 16 años, 5 meses
Puntos: 0
Exclamación Drama con SUM( multiplicación) a la vez

Hola todos, estoy trabajando en una empresa que se dedica ala comercialización de productos, Tiene un sistema que trabaja en Linux con PHP y MySql..
Mi problema es que tengo que llenar una tabla temporal diariamente para realizar un informe de gestión. La consulta

Código PHP:
select sum(db.CANTDESP*db.PRECUNIT),count(DISTINCT db.NUMRECOR) as cantidad_pedido1 from NOTDE_DB db 
join NOTV_DB tv on tv
.NUMREG=db.NUMRECOR
join ART_DB art on art
.NREGUIST=db.NCODART
join aclase6_codigo a on a
.codigo=art.CODIGO
where
tv
.FECHA between '2011-01-01 00:00:00' and '2011-01-25 23:59:59' and
tv.CODVEND=85 and                                         
a.nombre='Juan Soto'
La consulta sacaría la sumatoria de las ventas diarias de un vendedor y la cantidad de productos vendidos de un vendedor por un periodo, todo bien, el problema es cuando se ejecuta la consulta en Mysql se demora por un vendedor como 15 minutos existiria la manera de agilizarla ó realizarla de otra forma.

gracias
  #2 (permalink)  
Antiguo 03/07/2011, 14:53
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, 5 meses
Puntos: 2658
Respuesta: Drama con SUM( multiplicación) a la vez

Hay cosas realmente ineficientes en esa consulta:
- ¿Para qué consultar por el nombre del vendedor, si ya consultas por su código? Es más que redundante: Es innecesario. Y si la idea es poner el nombre en la consulta, bueno, no lo estás haciendo...
- JOIN no es exactamente igual a INNER JOIN. En tu caso es más eficiente usar INNER JOIN porque JOIN intenta primero hacer una junta entre campos con el mismo nombre, aunque tengan dominios distintos. Puede estar generando productos cartesianos.
- Preguntar por un campo DATETIME y contra valores DATETIME, cuando en realidad necesitas sólo la parte DATE, puede generar baja de performance. Exige al sistema leer más bytes innecesariamente.
- El orden de las tablas genera diferencias de resultado. Si te interesa la información de los vendedores, es mejor que la primera tabla sea la de lso vendedores. Si te interesa la de un solo vendedor, ni siquiera necesitas leer la tabla vendedores, si ya tienes su ID...

Hay si un detalle que no se termina de comprender. ¿Qué contiene exactamente la tabla "aclase6_codigo"?
Porque "ART_DB" parece ser la de artículos, "NOTV_DB" la de facturas o notas de venta, "NOTDE_DB" algo así como notas de débito, pero "aclase6_codigo" no se entiende.
Además, ¿Por qué aparece un campo "CODVEND" que parece ser el ID del vendedor, y luego usas el nombre para la búsqueda?

En esa parte, me parece que el problema mayor puede deberse a un diseño erróneo de tablas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 03/07/2011, 18:27
 
Fecha de Ingreso: noviembre-2007
Mensajes: 66
Antigüedad: 16 años, 5 meses
Puntos: 0
Respuesta: Drama con SUM( multiplicación) a la vez

Hola gnzsoloyo gracias por los comentarios si en verdad estoy de acuerdo contigo sobre el diseño, es una mierda, pero es lo que hay.
Lo del nombre error mió tienes razón.
Lo del inner entendía que era al revés, que el ínter se usaba para tablas idénticas, lo cambio y pruebo mañana en la pega.
Pregunto por datetime porque me dijeron que si no preguntaba por el horario 23:59:59 no tomaría todos los registros de ese día.
Los join los uso para unir tablas,
NOTDE_DB esta el detalle de lo Facturado
NOTV_DB lo facturado
ART_DB los códigos de los productos.
aclase6_codigo solo contiene los códigos que pertenecen a un canal específico, o marca.
Gracias por las observaciones modifico mañana en la pega y publico resultado.
  #4 (permalink)  
Antiguo 03/07/2011, 18:51
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, 5 meses
Puntos: 2658
Respuesta: Drama con SUM( multiplicación) a la vez

Bueno, tip final, podemos ajustarla un poquitín y veamos:
Código MySQL:
Ver original
  1.   SUM(db.CANTDESP * db.PRECUNIT) suma,
  2.   COUNT(DISTINCT db.NUMRECOR) cantidad_pedido1
  3.   NOTDE_DB db
  4.   NOTV_DB tv ON tv.NUMREG=db.NUMRECOR
  5.   ART_DB art ON art.NREGUIST=db.NCODART
  6.   INNER JOIN aclase6_codigo a ON a.codigo = art.CODIGO
  7.   (DATE(tv.FECHA) BETWEEN '2011-01-01' AND '2011-01-25')
  8.   AND
  9.   tv.CODVEND=85;

Por otro lado, es muy probable que puedas mejorarlo mucho definiendo algunos índices en datos claves. Pruébalo.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 04/07/2011, 07:27
 
Fecha de Ingreso: noviembre-2007
Mensajes: 66
Antigüedad: 16 años, 5 meses
Puntos: 0
Respuesta: Drama con SUM( multiplicación) a la vez

Que lata mala se demora lo mismo alguna otras ideas con join separados a la misma tabla a mi definitibamente se me terminaron las ideas.
  #6 (permalink)  
Antiguo 04/07/2011, 08:03
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, 5 meses
Puntos: 2658
Respuesta: Drama con SUM( multiplicación) a la vez

¿Por qué no nos muestras lo que te devuelve el análisis de EXPLAIN para tu consulta?
Eso nos peude dar una mejor idea de dónde se está produciendo el problema.
Usa algún front-end (phpMyadmin, por ejemplo) y ejecuta la consulta con EXPLAIN. Luego postea la tabla de datos que resulte.
Eso nos dará idea de a qué nos enfrentamos.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 04/07/2011, 08:44
 
Fecha de Ingreso: noviembre-2007
Mensajes: 66
Antigüedad: 16 años, 5 meses
Puntos: 0
Exclamación Respuesta: Drama con SUM( multiplicación) a la vez

Hola mira la consulta como la armo en local y corre bien

Código PHP:
select sum(db.CANTDESP*db.PRECUNIT), count(DISTINCT db.NUMRECOR) as cantidad_pedido1 
from NOTDE_DB db 
inner join NOTV_DB tv on tv
.NUMREG=db.NUMRECOR 
inner join ART_DB art on art
.NREGUIST=db.NCODART join aclase6_codigo a on a.codigo=art.CODIGO where (DATE(tv.FECHAbetween '2011-06-01 00:00:00' and '2011-06-28 23:59:59') and tv.CODVEND=84 and a.nombre='SP' 
estos datos se los pasos a un update denro de un ciclo for al mismo tiempo

Código PHP:
'update pp_vendedor_venta_meta set pedido_mes=10409900.00000, cantidad_pedido=4 WHERE id_pp_forecast_vendedor=84 and fecha='2011-06-28' and clase6='SP 

la respuesta de la consulta
Código PHP:
sum(db.CANTDESP*db.PRECUNIT)  cantidad_pedido1  
10409900.00000                                                 4 
Me trato de explicar la consulta me corre super bien y rapioda con pocos regsitros pero la tabla NOTDE tine como 5 registros, y las otras no bajan de los 1000 mi problema son los cruzes ò el calculo de la consulta, los cruzes por la cantidad de registros.
Por eso consultab si existia otra forma de realizar la consulta mà eficiente.
PD Tengo mi jefe respirandome enn el hombro me tiene chato.
  #8 (permalink)  
Antiguo 04/07/2011, 09:02
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, 5 meses
Puntos: 2658
Respuesta: Drama con SUM( multiplicación) a la vez

Te insisto: Usa el EXPLAIN y postea el resultado. Es lo mejor que puedes hacer en este punto.

Esta es tu consulta:

Código MySQL:
Ver original
  1.     SUM(db.CANTDESP*db.PRECUNIT),
  2.     COUNT(DISTINCT db.NUMRECOR) cantidad_pedido1
  3. FROM NOTDE_DB db
  4.     INNER JOIN NOTV_DB tv ON tv.NUMREG=db.NUMRECOR
  5.     INNER JOIN ART_DB art ON art.NREGUIST=db.NCODART
  6.     INNER JOIN aclase6_codigo a ON a.codigo=art.CODIGO
  7.     (DATE(tv.FECHA) between '2011-06-01' and '2011-06-28')
  8.     AND tv.CODVEND=84
  9.     AND a.nombre='SP'
Una cosa: Si estás poniendo ya la función DATE() como te lo dije, haz la comparación con las fechas sin horas. En este punto esa fuinción está suprimiendo las horas y sólo tomará en cuenta las fechas, ya no es necesario ese nivel de precisión

Toma la consulta y usa el EXPLAIN de las dos formas:
Código MySQL:
Ver original
  1.     SUM(db.CANTDESP*db.PRECUNIT),
  2.     COUNT(DISTINCT db.NUMRECOR) cantidad_pedido1
  3. FROM NOTDE_DB db
  4.     INNER JOIN NOTV_DB tv ON tv.NUMREG=db.NUMRECOR
  5.     INNER JOIN ART_DB art ON art.NREGUIST=db.NCODART
  6.     INNER JOIN aclase6_codigo a ON a.codigo=art.CODIGO
  7.     (DATE(tv.FECHA) between '2011-06-01' and '2011-06-28')
  8.     AND tv.CODVEND=84
  9.     AND a.nombre='SP'

Código MySQL:
Ver original
  1.     SUM(db.CANTDESP*db.PRECUNIT),
  2.     COUNT(DISTINCT db.NUMRECOR) cantidad_pedido1
  3. FROM NOTDE_DB db
  4.     INNER JOIN NOTV_DB tv ON tv.NUMREG=db.NUMRECOR
  5.     INNER JOIN ART_DB art ON art.NREGUIST=db.NCODART
  6.     INNER JOIN aclase6_codigo a ON a.codigo=art.CODIGO
  7.     (DATE(tv.FECHA) between '2011-06-01 00:00:00' and '2011-06-28 23:59:59')
  8.     AND tv.CODVEND=84
  9.     AND a.nombre='SP'
Luego copia la tabla resultado de esos EXPLAIN y posteanos lo que devuelven,.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 04/07/2011, 13:15
 
Fecha de Ingreso: noviembre-2007
Mensajes: 66
Antigüedad: 16 años, 5 meses
Puntos: 0
Respuesta: Drama con SUM( multiplicación) a la vez

Muchas gracias gnzsoloyo por la ayuda, con los inner joins mejoro el tiempo con la funcion date tambien, lo dejo asi ya que me pidiron que lo entregara


Código:
select sum(db.CANTDESP*db.PRECUNIT), count(DISTINCT db.NUMRECOR) as cantidad_pedido1 from NOTDE_DB db 
inner join NOTV_DB tv on tv.NUMREG=db.NUMRECOR
inner join ART_DB art on art.NREGUIST=db.NCODART
inner join aclase6_codigo a on a.codigo=art.CODIGO
where
(date(tv.FECHA) between '2011-06-01' and '2011-06-31') and
tv.CODVEND=84 and										 
a.nombre='SP';
gracias.
  #10 (permalink)  
Antiguo 04/07/2011, 13:21
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, 5 meses
Puntos: 2658
Respuesta: Drama con SUM( multiplicación) a la vez

Finalmente nos quedamos con la duda de qué es lo que devuelve el EXPLAIN de esa consulta.
¿Por qué no lo has posteado?
¿Lo hiciste? ¿Probaste el EXPLAIN?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #11 (permalink)  
Antiguo 04/07/2011, 13:23
 
Fecha de Ingreso: noviembre-2007
Mensajes: 66
Antigüedad: 16 años, 5 meses
Puntos: 0
Respuesta: Drama con SUM( multiplicación) a la vez

No lo proble, no lo se utilizar
  #12 (permalink)  
Antiguo 04/07/2011, 13:36
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, 5 meses
Puntos: 2658
Respuesta: Drama con SUM( multiplicación) a la vez

TE lo puse en el post #8, escrito tal y como lo debes usar.
Simplemente tenías que copiar la consulta y usarla como está:
Código MySQL:
Ver original
  1.     SUM(db.CANTDESP*db.PRECUNIT),
  2.     COUNT(DISTINCT db.NUMRECOR) cantidad_pedido1
  3. FROM NOTDE_DB db
  4.     INNER JOIN NOTV_DB tv ON tv.NUMREG=db.NUMRECOR
  5.     INNER JOIN ART_DB art ON art.NREGUIST=db.NCODART
  6.     INNER JOIN aclase6_codigo a ON a.codigo=art.CODIGO
  7.     (DATE(tv.FECHA) BETWEEN '2011-06-01' AND '2011-06-28')
  8.     AND tv.CODVEND=84
  9.     AND a.nombre='SP'
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #13 (permalink)  
Antiguo 04/07/2011, 13:46
 
Fecha de Ingreso: noviembre-2007
Mensajes: 66
Antigüedad: 16 años, 5 meses
Puntos: 0
Respuesta: Drama con SUM( multiplicación) a la vez

Esto retorna


Código:
id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra  
1 SIMPLE db ALL NULL NULL NULL NULL 7   
1 SIMPLE tv ALL NULL NULL NULL NULL 7 Using where 
1 SIMPLE a ALL NULL NULL NULL NULL 765 Using where 
1 SIMPLE art eq_ref PRIMARY,CODIGO,NREGUIST PRIMARY 4 m_suite.db.NCODART 1 Using where
  #14 (permalink)  
Antiguo 04/07/2011, 13:54
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, 5 meses
Puntos: 2658
Respuesta: Drama con SUM( multiplicación) a la vez

En principio, lo que se ve en ese reporte es que aclase6_codigo es la tabla más ineficiente. Es probable que la consulta mejore un tanto si le creas un índice sobre el campo codigo.
Por otro lado, tal parece que los campos relacionados de las otras tablas no son en realidad FK, como si las tablas fuesen MyISAM y no InnoDB, por lo que en realidad no está usando índices para vincularlos y eso puede hacer la consulta algo lenta.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #15 (permalink)  
Antiguo 04/07/2011, 13:59
 
Fecha de Ingreso: noviembre-2007
Mensajes: 66
Antigüedad: 16 años, 5 meses
Puntos: 0
Respuesta: Drama con SUM( multiplicación) a la vez

Gracias gnzsoloyo el reporte lo tomo mi jefe que el maneja la BD, yo no puedo realizar cambios,tampoco me da acceso a la BD real.
Yo creo que me estan jorobando pero == estoy de paso en este trabajo y la PR va ==, nunca habia trabajado en un lugar don de las tablas no tengan una buen estructura y menos indices.

gracias.

Etiquetas: sum
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 18:22.