Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MySQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=21)
-   -   MySQL LENTO al hacer INSERT INTO sucesivamente (https://www.clubdelphi.com/foros/showthread.php?t=61701)

golf2008 18-11-2008 21:49:43

MySQL LENTO al hacer INSERT INTO sucesivamente
 
Hola a todos:
Les cuento a ver si a alguien le pasó. Trabajo con Delphi 5 y Zeos.
Con MySQL todo bien, pero a la hora de tener que hacer varios INSERT INTO (dentro de un ciclo), se pone demasiado lento.

Para los que han realizado un sistema comercial integrado con la contabilidad de la empresa, cada vez que se registra una factura hay que hacer un asiento contable por cada producto que integra la factura, dado que cada producto puede tener una imputación contable distinta.

Supongamos una factura de 20 productos, me demora 9 segundos viendo el TXT del ZSQLMonitor. Ni quiero pensar implementado en red lo que va a demorar.

Desde ya muchas gracias.

AzidRain 19-11-2008 00:05:29

Nada tiene que ver la lentitud en tu caso con el motor. No das muestra de código, lo cual ayudaría mucho. Yo hice algo similar y como lo ataqué fue creando una clase TAsientoFactura a la que le paso el ID de la factura que quiero contabilizar y hago ahi toda la lógica.

Si pones el trozo de código que contiene el ciclo te podremos ayudar un poco màs.

golf2008 19-11-2008 13:06:21

Va el código:
Por cada producto este código se ejecuta tres veces, una por cada renglón del asiento. Si la factura tiene 20 producto, el código se ejecuta unas 60 veces

MD.ZAsientos.SQL.Clear;
MD.ZAsientos.SQL.Text:='INSERT INTO asientos (fecha,cuenta,debe,haber,saldo,comentario,numero,comp,numcom,codprov)'+
'VALUES (:fecha,:cuenta,:debe,:haber,:saldo,:comentario,:numero,:comp,:numcom,:codprov)';
MD.ZAsientos.ParamByName('fecha').Value:=StrtoDate(fecha.text);
MD.ZAsientos.ParamByName('cuenta').Value:=MD.DetalleImputa.Value;
MD.ZAsientos.ParamByName('Debe').Value:=MD.DetalleNetograv.Value;
MD.ZAsientos.ParamByName('comentario').Value:=comentario;
MD.ZAsientos.ParamByName('Numero').value:=nasiento;
MD.zAsientos.ParamByName('Comp').value:=MD.DetalleTipo.Value;
MD.zAsientos.ParamByName('Numcom').Value:=MD.DetalleNumcom.Value;
MD.zAsientos.ParamByName('Codprov').Value:=MD.DetalleCod_prov.Value;
MD.ZAsientos.ExecSQL;

Desde ya muchas gracias

seoane 19-11-2008 13:22:19

Hace poco tuve que hacer un programa que básicamente hacia un montón de Insert en una tabla de MySql y el proceso tardaba muchísimo (te podías ir a tomar un café :D ), hasta que descubrí que MySql permite la inserción múltiple, es decir, insertar varios registros de una vez.

Por ejemplo (ayuda de MySQL):
Código SQL [-]
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

Podrías probar a construir tu mismo la consulta e insertar todos los productos de la factura en una sola sentencia.

duilioisola 19-11-2008 14:16:57

Y no tendrá que ver con las transacciones?
Yo trabajo con Firebird y depende de si utilizo Commit o CommitRetaining, la cosa cambia mucho.
Código Delphi [-]
while (no_se_terminen_los_datos) do
begin
   if (not MD.ZAsientos.Transaction.InTransaction) then
      MD.ZAsientos.Transaction.StartTransaction;
   MD.ZAsientos.SQL.Clear;
   MD.ZAsientos.SQL.Text:='INSERT INTO asientos (fecha,cuenta,debe,haber,saldo,comentario,numero,comp,numcom,codprov) '+
   'VALUES (:fecha,:cuenta,:debe,:haber,:saldo,:comentario,:numero,:comp,:numcom,:codprov)';
   MD.ZAsientos.ParamByName('fecha').Value:=StrtoDate(fecha.text);
   MD.ZAsientos.ParamByName('cuenta').Value:=MD.DetalleImputa.Value;
   MD.ZAsientos.ParamByName('Debe').Value:=MD.DetalleNetograv.Value;
   MD.ZAsientos.ParamByName('comentario').Value:=comentario;
   MD.ZAsientos.ParamByName('Numero').value:=nasiento;
   MD.zAsientos.ParamByName('Comp').value:=MD.DetalleTipo.Value;
   MD.zAsientos.ParamByName('Numcom').Value:=MD.DetalleNumcom.Value;
   MD.zAsientos.ParamByName('Codprov').Value:=MD.DetalleCod_prov.Value;
   MD.ZAsientos.ExecSQL;
   MD.ZAsientos.Transaction.Commit;
end;

También puede tener que ver con los triggers que ejecute al insertar en esa tabla.

heymatias 19-12-2008 00:59:54

Hola, soy nuevo en el foro y nuevo con Delphi. Pero laburo con MySQL desde hace años y te aseguro que hacer varias insersiones es muchísimo más lento que hacer una inserción enorme que haga todo.

Podés hacer una consulta del tipo

INSERT INTO.... ; INSERT INTO...;INSERT INTO.... ; INSERT INTO...;

... y así. La idea es que mover el motor de MySQL cuesta un poco, y si vos hacés todas las inserciones por separado lo estás moviendo cada vez, en cambio, si le dás todas las inserciones para hacer él se encarga de optimizar las mismas.

Cuanto más puedas delegar al motor mejor, está muy bien programado y nada de lo que vos programes va a ser más rápido.


Y fijate de hacer transacciones, porque si grabás la factura y no los asientos vas a tener problemas.


Saludos, matías.-


La franja horaria es GMT +2. Ahora son las 01:32:17.

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