Ir al contenido


Foto

Lentitud en actualización


  • Por favor identifícate para responder
22 respuestas en este tema

#1 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 27 marzo 2009 - 02:33

tengo la siguiente instruccion para la  actualización de la base de datos




sql
  1. UPDATE productos SET PrecioSinIva1 = (PrecioVenta1) / (1 + (AlicuotaVenta / 100)),
  2. PrecioSinIva2 = (PrecioVenta2 / (1 + (AlicuotaVenta / 100)),
  3. PrecioSinIva3 = (PrecioVenta3) / (1 + (AlicuotaVenta / 100)),
  4. PrecioSinIva4 = (PrecioVenta4) / (1 + (AlicuotaVenta / 100))



el asunto es que con unos 500 o 600 registros la consulta se torna insoportablemente lenta.... 
  • 0

#2 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 27 marzo 2009 - 02:53

Hola eduardo,
¿Desde donde estás lanzando la instrucción SQL? ¿Desde tu aplicación, o de forma interna a la DB como ser desde un trigger o SP?
¿Indices? ¿Haces otros cálculos, cuantos y que tan complicados son?
¿Que tienes en la condición WHERE?

Disculpa mi bombardeo de preguntas, nomás quiero asegurarme de por donde puede venir la lentitud.

Saludos,
  • 0

#3 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 27 marzo 2009 - 03:01

Aunque sea dificil tratare de contestarte en secuencia ;)

Hola eduardo,


Hola Delphius :D:D

¿Desde donde estás lanzando la instrucción SQL? ¿Desde tu aplicación, o de forma interna a la DB como ser desde un trigger o SP?


Desde la aplicacion, en un TZQuery con la propiedad requestlive en true y el TZconnection la propiedad autocommit en true

¿Indices?


la clave primaria, el codigo del producto


¿Haces otros cálculos, cuantos y que tan complicados son?


nop, es una instruccion sencilla y no se dispara ningun trigger

¿Que tienes en la condición WHERE?


nada, tengo que actualizarlos todos, pero solo son unos 500 o 600

Disculpa mi bombardeo de preguntas, nomás quiero asegurarme de por donde puede venir la lentitud.

Saludos,


yo tambien tengo ganas de saber lo mismo :D:D
  • 0

#4 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 27 marzo 2009 - 03:31

Pues si que es raro.

Hice una prueba, desde el IbExpert (es el que tengo abierto y para hacer una prueba rápida) contra una tabla que tiene casi el doble de registros, con unas operaciones más sencillas que tu (no da para muchas operaciones los campos que tengo) y el resultado es inmediato. E intuyo que si lo hago desde una aplicación de prueba el resultado será bastante similar.

¿Cuantos campos debe actualizarse? ¿Hasta cuantos "PrecioSinIVA" tienes?

No manejo Zeos amigo... en algunos lados se dice que en ocasiones Zeos es lento en Firebird, yo no puedo asegurar el rumor porque no los probé. ¿No habrá algo entre las propiedades que afecte a la velocidad?

¿No habrá otras tareas ejecutándose como otras consultas, transacciones, etc?

Saludos,
  • 0

#5 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 27 marzo 2009 - 03:35

Hola.

Genera esa misma instrucción desde IBX para verificar si el problema es realmente Zeos, si es la misma lentitud ya podremos ver por otro lado... por ejemplo, esta tu base en red?????

Salud OS
  • 0

#6 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 27 marzo 2009 - 03:44

esta en local, voy a probar en ibexpert a ver...
  • 0

#7 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 27 marzo 2009 - 03:46

esta en local, voy a probar en ibexpert a ver...


Mas bien quise decir con el componente IBX de Delphi :D

Salud OS
  • 0

#8 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 27 marzo 2009 - 04:06

ya se por donde viene la cosa, y no es en esa instruccion, es en esta:



sql
  1. UPDATE productos SET PorcUtilidad1 = ((PrecioSinIva1 - CostoUnitario) / PrecioSinIva1) * 100,
  2. PorcUtilidad2 = ((PrecioSinIva2 - CostoUnitario) / PrecioSinIva2) * 100,
  3. PorcUtilidad3 = ((PrecioSinIva3 - CostoUnitario) / PrecioSinIva3) * 100,
  4. PorcUtilidad4 = ((PrecioSinIva4 - CostoUnitario) / PrecioSinIva4) * 100



Cuando uno de los precios esta en 0, me da error de division por zero, pero no se lanza la excepcion.

hay una forma de colocar un condicional, que si uno de los precios es cero no se actualize ese precio en especifico pero el resto si...


Ahora lo que me extraña es que la primera instruccion a pesar de haber precios en cero no salte ese error.
  • 0

#9 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 27 marzo 2009 - 04:27

Hola

Puedes usar la función Coalesce(Campo,valor_en_error)



sql
  1. UPDATE productos SET PorcUtilidad1 = ((PrecioSinIva1 - CostoUnitario) / COALESCE(PrecioSinIva1,1) ) * 100,
  2. PorcUtilidad2 = ((PrecioSinIva2 - CostoUnitario) / COALESCE(PrecioSinIva2,1) ) * 100,
  3. PorcUtilidad3 = ((PrecioSinIva3 - CostoUnitario) / COALESCE(PrecioSinIva3,1) ) * 100,
  4. PorcUtilidad4 = ((PrecioSinIva4 - CostoUnitario) / COALESCE(PrecioSinIva4,1) ) * 100



Nota, le ponemos al valor_en_error "1" para que sea una division entre 1 en caso de error.

Salud OS
  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 27 marzo 2009 - 04:29

Hola Eduardo,
Ummm *-)... estoy pensando...
Tal vez empleando IIF, Coalesce o alguna otra... pero creo que eso ya termina complicando más la instrucción SQL.

Yo en todo caso optarí­a por disponer de un SP que lance el UPDATE de los registros, previa consulta del valor de los campos y mediante el condicional hacer una u otra cosa.
Es decir que por cada registro vas viendo si es cero los campos PrecioSinIVA y en base a ello calculas el nuevo valor, en otro caso asumes que es cero.

Luego actualizas dicho campo.

No se, es una idea... a lo mejor hay otras.

Saludos,
  • 0

#11 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 27 marzo 2009 - 05:09

Hola Eduardo,
Ummm *-)... estoy pensando...
Tal vez empleando IIF, Coalesce o alguna otra... pero creo que eso ya termina complicando más la instrucción SQL.

Yo en todo caso optarí­a por disponer de un SP que lance el UPDATE de los registros, previa consulta del valor de los campos y mediante el condicional hacer una u otra cosa.
Es decir que por cada registro vas viendo si es cero los campos PrecioSinIVA y en base a ello calculas el nuevo valor, en otro caso asumes que es cero.

Luego actualizas dicho campo.

No se, es una idea... a lo mejor hay otras.

Saludos,


Hola

Yo creo que no es necesario hacer todo lo que dices amigo Delphius, pienso que esto solo lo quiere hacer una sola vez.

Salud OS
  • 0

#12 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 27 marzo 2009 - 08:41

Una vez, siempre que Chavez amanezca de ganas de modificar el IVA  :@


La pega que le veo a tu solucion Delpius es que tendria que hacer el proceso campo por campo, cosa que a mi entender volveria pesada la consulta, pero a fin de cuentas tampoco es que entienda mucho de esto jejeje...


Voy a probar con coalesce, pero creo que es solo para nulos... de todas formas mañana los actualizo.,..
  • 0

#13 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 27 marzo 2009 - 09:57

Por eso digo, que es una sola vez, y se usa Coalesce() :p

Jejeje.

Pues entonces amigo mejor no intentes mi idea, Porque no es del todo práctica. No he probado el código de Eliseo pero creo que va a andar.
En realidad no es campo a campo, sino registro a registro.

La idea que me imagino es:



sql
  1. CREATE PROCEDURE ActualizarPorcentajeUtilidad
  2. ...
  3. AS
  4. DECLARE variable PrecioIVA1 NUMERIC(15,2); -- Poner el tipo indicado
  5. ...
  6. DECLARE variable PrecioIVA4 NUMERIC(15,2);
  7. BEGIN
  8. -- ejecutamos la consulta SQL select con los valores...
  9. FOR excecute statement
  10.     'select ID, PrecioSinIVA1, ... PrecioSinIVA4,
  11.               CostoUnitario' INTO :_ID :PrecioIVA1, ... :PrecioIVA4, :CostoU
  12. do
  13.   -- ¿el precio del iva puede ser cero?
  14.   IF (PrecioIVA1 = 0) OR (PrecioIVA IS NULL) THEN PrecioIVA = 1;
  15.   ...
  16.   IF (PrecioIVA4 = 0) OR (PrecioIVA IS NULL) THEN PrecioIVA = 1;
  17.  
  18.   -- actualizamos registro a registro. ¿deberí­a ir el filtro where?
  19.   UPDATE productos SET
  20.     PorcUtilidad1 = ((PrecioIVA1 - CostoUnitario) / PrecioIVA1) * 100,
  21.     PorcUtilidad2 = ((PrecioIVA2 - CostoUnitario) / PrecioIVA2) * 100,
  22.     PorcUtilidad3 = ((PrecioIVA3 - CostoUnitario) / PrecioIVA3) * 100,
  23.     PorcUtilidad4 = ((PrecioIVA4 - CostoUnitario) / PrecioIVA4) * 100
  24.     WHERE ID = _ID;
  25.   suspend;
  26. END



No he probado mi SP, lo más probable que tenga alguna fallita :p

Saludos,
  • 0

#14 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 27 marzo 2009 - 10:14

Eduardo espero que no te moleste, edité tus mensajes para ajustar las consultas. Estaban un tanto horizontal ;)

Saludos,
  • 0

#15 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 28 marzo 2009 - 06:14

claro que pruebo tu idea amigo, lo anterior no fue una afirmacion, solo una duda que tenia....
  • 0

#16 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 28 marzo 2009 - 07:47

que les parece esto:



sql
  1. UPDATE productos SET PorcUtilidad1 = ((PrecioSinIva1 - CostoUnitario) / iif(PrecioSinIva1= 0, 1, PrecioSinIva1)) * 100,
  2. PorcUtilidad2 = ((PrecioSinIva2 - CostoUnitario) / iif(PrecioSinIva2= 0, 1, PrecioSinIva2)) * 100,
  3. PorcUtilidad3 = ((PrecioSinIva3 - CostoUnitario) / iif(PrecioSinIva3= 0, 1, PrecioSinIva3)) * 100,
  4. PorcUtilidad4 = ((PrecioSinIva4 - CostoUnitario) / iif(PrecioSinIva4= 0, 1, PrecioSinIva4)) * 100



El codigo de Delphius aun no lo he probado y Coalesce no sirve...
  • 0

#17 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 28 marzo 2009 - 08:14

Saludos.

Creo que para obtener el resultado deseado, deberás de usar Coalesce ligado con IIF, así­ Coalesce se lleva los nulos por ceros y IIF les pone uno en caso de ser cero.
  • 0

#18 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 28 marzo 2009 - 08:50

buena idea Rolphy, no habia pensado en los nulos..
  • 0

#19 joseme

joseme

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 62 mensajes
  • LocationCosta Rica

Escrito 28 marzo 2009 - 07:59

eduarcol, me parece que lo podrí­as poner así­:

set PorcUtilidadX=iif(coalesce(Preciox,0)=0,0,(Preciox-Costox)/Preciox*100)
  • 0

#20 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 28 marzo 2009 - 10:25

esta buena esa, me ahorraria una ejecucion en caso de que sea cero...  (h)
  • 0




IP.Board spam blocked by CleanTalk.