Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Mi Consulta SQL Funciona pero tarda demasiado (https://www.clubdelphi.com/foros/showthread.php?t=95928)

webmasterplc 28-10-2022 07:45:52

Mi Consulta SQL Funciona pero tarda demasiado
 
Buenas estoy realizando un procedimiento para consolidar los datos de varias tablas en un sola, todas tiene la misma estructura, el problema es que el proceso tarda demasiado y mientras lo hace me cuelga la maquina y no se por donde va (uso tablas dbisam, no las uso por eleccion)
mi codigo es este
Código Delphi [-]
 
with sqnominadetalle do
  begin
    close;
    SQL.Clear;
    SQL.Add('SELECT * FROM a2NominaDetalle');
    ExecSQL;
    sqnominadetalle.First;
    while not sqnominadetalle.Eof do
    begin
      cedintegrante := sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString;
      codconstante := sqnominadetalle.FieldByName('FNM_CONSTANTE').AsString;
      fnmtipo := sqnominadetalle.FieldByName('FNM_TIPO').AsInteger;
      fnmvalorperiodo := sqnominadetalle.FieldByName('FNM_VALORPERIODO').AsCurrency;
      fnmvalordefault := sqnominadetalle.FieldByName('FNM_VALORDEFECTO').AsCurrency;
      fnmdescripcion := sqnominadetalle.FieldByName('FNM_DESCRIPCIONPERIODO').AsString;
      with sqverificardetalle do
      begin
        close;
        ParamByName('PINTEGRANTE').AsString := cedintegrante;
        ParamByName('PCONSTANTE').AsString := codconstante;
        ExecSQL;
        if not sqverificardetalle.IsEmpty then
        begin
          with squpdatenomina do
          begin
            ParamByName('PTIPO').AsInteger := fnmtipo;
            ParamByName('PCONSTANTE').AsString := codconstante;
            ParamByName('PINTEGRANTE').AsString := cedintegrante;
            ParamByName('PVALOR1').AsCurrency := fnmvalordefault;
            ParamByName('PVALOR2').AsCurrency := fnmvalorperiodo;
            ParamByName('PPERIODO').AsString := fnmdescripcion;
            ExecSQL;
            close;
          end

        end
        else
        begin
          with dbtsdetallenomina do
          begin

            tablename := 'a2NominaDetalle';
            Open;
            Insert;
            Append;
            FieldByName('FNM_TIPO').AsInteger := fnmtipo;
            FieldByName('FNM_CONSTANTE').AsString := codconstante;
            FieldByName('FNM_INTEGRANTE').AsString := cedintegrante;
            FieldByName('FNM_VALORDEFECTO').AsCurrency := fnmvalordefault;
            FieldByName('FNM_VALORPERIODO').AsCurrency := fnmvalorperiodo;
            FieldByName('FNM_DESCRIPCIONPERIODO').AsString := fnmdescripcion;
            Post;
            close;
          end;
        end;
        close;
      end;
      // ShowMessage('Net');
      sqnominadetalle.Next;
    end;

    with sqstatus do
    begin
      close;
      SQL.Clear;
      SQL.Add('UPDATE SEDES SET SED_STATUS = :PSTATUS');
      SQL.Add('WHERE ID_SEDE=:PIDSEDE');
      ParamByName('PIDSEDE').AsString := codsede;
      ParamByName('PSTATUS').AsInteger := 2;
      ExecSQL;
    end;
  end;

Neftali [Germán.Estévez] 28-10-2022 09:07:57

Estaría bien que explicaras un poco lo que deseas hacer, facilita el que los demás puedan entenderlo, más que tener que revisar el código.
Por otro lado das pocos datos para saber dónde está la parte que "tarda demasiado".

Lo primero sería añadir un log de tiempo a ese código para saber qué parte está tardando.
También estaría bien saber de cuantos registros hablamos (en cada uno de los Datasets -sqnominadetalle, sqverificardetalle, squpdatenomina, dbtsdetallenomina,...-).

Una vez que añadas los de tiempos y sepas qué parte tarda, se pueden revisar si faltan índices en las tablas para las búsquedas (por ejemplo).

Por otro lado veo que primero ejecutas una consulta con sqnominadetalle y para cada registro que recorres con un while, realizas una nueva búsqueda con sqverificardetalle, utilizando los parámetros PINTEGRANTE y PCONSTANTE.

Código Delphi [-]
    while not sqnominadetalle.Eof do
    begin
      cedintegrante := sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString;
      codconstante := sqnominadetalle.FieldByName('FNM_CONSTANTE').AsString;
      fnmtipo := sqnominadetalle.FieldByName('FNM_TIPO').AsInteger;
      fnmvalorperiodo := sqnominadetalle.FieldByName('FNM_VALORPERIODO').AsCurrency;
      fnmvalordefault := sqnominadetalle.FieldByName('FNM_VALORDEFECTO').AsCurrency;
      fnmdescripcion := sqnominadetalle.FieldByName('FNM_DESCRIPCIONPERIODO').AsString;
      with sqverificardetalle do
      begin
        close;
        ParamByName('PINTEGRANTE').AsString := cedintegrante;
        ParamByName('PCONSTANTE').AsString := codconstante;
        ExecSQL; 
        ...

Deberías intentar realizar eso utilizando una única consulta con una JOIN, De esa forma aunque la consulta será más costosa, pero te evitarás lanzar las consultas de dentro del WHILE.

Se puede seguir, pero es un poco dar palos de ciego sin saber más detalles...

kuan-yiu 28-10-2022 09:14:51

También añadiría, de modo general, que si las tablas tienen muchos campos no hagas un " Select * ", siempre es mejor listar los campos usados y solo los usados.

Casimiro Notevi 28-10-2022 10:49:30

Falta muchísima información para poder ayudar, como han comentado los compañeros, pero si se trata de pasar una tabla completa a otra, y que tiene la misma estructura, es más simple algo como:
Código SQL [-]
Insert into tabla2 (select * from tabla1);

webmasterplc 28-10-2022 12:34:25

Buenas tengo las datas en diferentes capetas y en mi proyecto dos db origen y destino
Código Delphi [-]
//etsa consulta se hace en la tabla a2NominaDetalle de la sede o sucursal
with sqnominadetalle do
  begin
    close;
    SQL.Clear;
    SQL.Add('SELECT * FROM a2NominaDetalle');
    ExecSQL;
    sqnominadetalle.First;
    while not sqnominadetalle.Eof do
    begin
      cedintegrante := sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString;
      codconstante := sqnominadetalle.FieldByName('FNM_CONSTANTE').AsString;
      fnmtipo := sqnominadetalle.FieldByName('FNM_TIPO').AsInteger;
      fnmvalorperiodo := sqnominadetalle.FieldByName('FNM_VALORPERIODO').AsCurrency;
      fnmvalordefault := sqnominadetalle.FieldByName('FNM_VALORDEFECTO').AsCurrency;
      fnmdescripcion := sqnominadetalle.FieldByName('FNM_DESCRIPCIONPERIODO').AsString;

luego en la tabla a2NominaDetalle destino o casa matriz hago una consulta para verificar si el registro existe
Código Delphi [-]
 with sqverificardetalle do
      begin
        close;
        ParamByName('PINTEGRANTE').AsString := cedintegrante;
        ParamByName('PCONSTANTE').AsString := codconstante;
        ExecSQL;
        if not sqverificardetalle.IsEmpty then
        begin
          with squpdatenomina do
          begin
            ParamByName('PTIPO').AsInteger := fnmtipo;
            ParamByName('PCONSTANTE').AsString := codconstante;
            ParamByName('PINTEGRANTE').AsString := cedintegrante;
            ParamByName('PVALOR1').AsCurrency := fnmvalordefault;
            ParamByName('PVALOR2').AsCurrency := fnmvalorperiodo;
            ParamByName('PPERIODO').AsString := fnmdescripcion;
            ExecSQL;
            close;
          end

        end
        else
        begin
 //Este Caso de Insertar un registro es poco probable que exista        
 with dbtsdetallenomina do
          begin

            tablename := 'a2NominaDetalle';
            Open;
            Insert;
            Append;
            FieldByName('FNM_TIPO').AsInteger := fnmtipo;
            FieldByName('FNM_CONSTANTE').AsString := codconstante;
            FieldByName('FNM_INTEGRANTE').AsString := cedintegrante;
            FieldByName('FNM_VALORDEFECTO').AsCurrency := fnmvalordefault;
            FieldByName('FNM_VALORPERIODO').AsCurrency := fnmvalorperiodo;
            FieldByName('FNM_DESCRIPCIONPERIODO').AsString := fnmdescripcion;
            Post;
            close;
          end;
        end;
        close;
      end;
   
      sqnominadetalle.Next;
    end;
en el segundo bloque es donde tarda demasiado
y por ultimo cambio el status

Casimiro Notevi 28-10-2022 15:05:00

Antes has dicho 2 tablas y ahora 2 bases de datos.

webmasterplc 28-10-2022 15:22:00

disculpen no me supe explicar son dos tablas pero están en dos bd distintas

Casimiro Notevi 28-10-2022 16:31:59

¿Pero exactamente qué quieres hacer? ¿pasar los datos de una a la otra? ¿y si existe un registro con la misma clave primaria entonces no lo pasa, lo actualiza o qué debe hacer?

webmasterplc 28-10-2022 17:47:09

Si no existe lo inserto (Esto casi no ocurre) y si existe actualizar

Casimiro Notevi 28-10-2022 19:25:41

Si fuese en la misma base de datos sería facilísimo:
Código SQL [-]
insert or update into table2 (select * from table1);
Si esa BD que usas puedes hacer eso, perfecto, en caso contrario.

Código Delphi [-]
select * from tabla1;
while not tabla1.eof  
  try
    insert into tabla 2...
  except
    update table 2...
  end;
  table1.next
end;

mamcx 28-10-2022 20:12:50

Cita:

Empezado por webmasterplc (Mensaje 548833)
el proceso tarda demasiado y mientras lo hace me cuelga la maquina y no se por donde va

Bueno, igual que los demás compañeros falta información, pero estos puntos son generales en cualquier proceso de carga de datos (ELT).

Asi que:

1. Cuanto es "demasiado"?
2. Para que no se "cuelgue" la app lo pones dentro de un Thread o en un proceso aparte y vas comunicando el progreso
3. Para "saber por donde va" es critico que tengas integrado un Log con el resultado de cada paso.
4. Los procesos de ELT se hacen en batch. Algo asi como "cargar cada 500 registros"

Si tienes una base de datos no muy moderna o limitada (que supongo es el caso con dbisam), un método que uso, ya que me toca integrar con muchas fuentes de datos, es cargar los IDs de lo que quiero checar en un hasmap y usarlo para comparar de forma rápida. Algo asi como (pseudo-codigo):

Código Delphi [-]

mi_indice := SELECT id FROM db1.Customer

for row in SELECT * FROM db2.Customer 
begin
   if row.id in mi_indice 
   begin
   // Existe
  end else begin
  //No existe
  end;
end

Asi debería ser muy rapido, mas que hacer un select en cada ciclo.

webmasterplc 28-10-2022 20:46:24

1. Cuanto es "demasiado"?
Tarda mas de 20 minutos con una tabla de 120 registros.
2. Para que no se "cuelgue" la app lo pones dentro de un Thread o en un proceso aparte y vas comunicando el progreso
Voy a Informar,e de esto ya que no lo manejo
3. Para "saber por donde va" es critico que tengas integrado un Log con el resultado de cada paso.
Voy a Hacerlo
4. Los procesos de ELT se hacen en batch. Algo asi como "cargar cada 500 registros"
Perfecto

Voy a probar lo que propones

Casimiro Notevi 29-10-2022 11:55:59

Cita:

Empezado por webmasterplc (Mensaje 548857)
Tarda mas de 20 minutos con una tabla de 120 registros.

Tardo menos en teclear manualmente los registros :D

mamcx 29-10-2022 19:46:51

Cita:

Empezado por Casimiro Notevi (Mensaje 548859)
Tardo menos en teclear manualmente los registros :D

Como estaba de despistado que no note que eran 120 registros!.

Asi, todo lo que dije es "overkill". La forma mas eficiente entonces es mucho mas simple:

Carga todos los registros al inicio en un DataSet en memoria y haz los procesos contra ese.

Código Delphi [-]
var original: TClientDataset = SELECT * FROM db1.source
var destino: TClientDataset = SELECT * FROM db2.dest

// procesas todo en memoria

// Guarda los resultados de destino

webmasterplc 01-11-2022 03:48:03

Buenas ae ido trabajando siguiendo las recomendaciones, ese procedimiento esta en el evento onclick de un boton, estoy tratando de hacer un procedure para luego llamarlo e un thread pero al hacer el procedure no veo los objetos query y table.
por Ejemplo asi veo los objetos

Código Delphi [-]
procedure TformMenu.btn2Click(Sender: TObject);

begin
     sqsedes.Active:=False;
     sqsedes.Active:=True;
end;
pero si intento hacerlo
Código Delphi [-]
procedure consolidar;

begin
     sqsedes.Active:=False;
     sqsedes.Active:=True;
end;
no veo los query

Casimiro Notevi 01-11-2022 10:23:33

¿Y eso qué tiene que ver con lo que te hemos aconsejado?
Creo que te estás liando, o puede que no te hayamos entendido lo que quieres hacer realmente.

Casimiro Notevi 01-11-2022 12:53:14

Es que no tiene sentido que te compliques la vida con hilos y cosas raras para unos pocos registros, eso debe tardar segundos.
Por ejemplo, una simple prueba para que te hagas una idea, tengo una tabla con más de 250.000 registros (y unos 90 campos) y los paso a otra tabla igual, tiempo: 2,6 segundos.
En tu caso, con BD distintas y comprobando los que ya existen para actualizarlos, por código Delphi, etc. calcúlale unos 3 a 5 segundos... como mucho.



webmasterplc 02-11-2022 02:15:55

En el procedimiento la mayoria son update porque verifico que si existe lo actualice y si no existe lo inserte

kuan-yiu 02-11-2022 08:28:10

Yo tengo un proceso de migración que trabaja sobre tres tablas de la misma BD (una con 25.000 tuplas y las otras con menos de 500) haciendo varias selecciones parciales con sus respectivos bucles, comparaciones, cálculos, inserciones, actualizaciones (de saldos)... y en el peor de los escenarios tarda 3 minutos.

Neftali [Germán.Estévez] 02-11-2022 11:37:37

Cita:

Empezado por webmasterplc (Mensaje 548884)

procedure TformMenu.consolidar;
begin
sqsedes.Active:=False;
sqsedes.Active:=True;
end;

no veo los query

Ese procedimiento consolidar no es de clase (como el otro). No tiene la parte en rojo para que me entiendas.
Tienes 2 opciones:

1) Definirlo dentro de la clase (parte privada).
2) Pasarle los objetos necesarios como parámetros.

Por otro lado, trabajar con Threads y Base de datos no es trivial. Las conexiones no suelen ser Threadsafe, así que al thread ademas de pasarle toda la información necesaria para trabajar, deberás dotarle de lo necesario (ConnectionString, por ejemplo) para crear una nueva conexión sobre la Base de Datos.

duilioisola 02-11-2022 16:00:28

Mi granito de arenta:

Un simple log puede ser un procedimiento como este:
Código Delphi [-]
procedure TDMMain.Log(s: string);
var
  F : TextFile;
  FileName : string;
begin
  FileName := ChangeFileExt(Application.ExeName, '.log');
  AssignFile(F, FileName);
  try
     Append(F);
  except
     try
        Rewrite(F);
     except
        on e: Exception do
           ShowMessage('Error al abrir fichero : ' + FileName + #13#10 + e.Message);
     end;
  end;
  WriteLn(F, FormatDatetime('[yyyy-mm-dd hh:nn:ss.zzz] ', Now) + s);
  CloseFile(F);
end;

Prueba el bulce principal sin hacer nada y ves cuanto tarda.
Código Delphi [-]
with sqnominadetalle do
  begin
    close;
    SQL.Clear;
    SQL.Add('SELECT * FROM a2NominaDetalle');
    ExecSQL;
    sqnominadetalle.First;
    while not sqnominadetalle.Eof do
    begin
      Log(sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString);

      sqnominadetalle.Next;
    end;
  end;
Si es algo lógico (segundos), agregas la validación:
Código Delphi [-]
with sqnominadetalle do
  begin
    close;
    SQL.Clear;
    SQL.Add('SELECT * FROM a2NominaDetalle');
    ExecSQL;
    sqnominadetalle.First;
    while not sqnominadetalle.Eof do
    begin
      Log(sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString);
      
      cedintegrante := sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString;
      codconstante := sqnominadetalle.FieldByName('FNM_CONSTANTE').AsString;
      fnmtipo := sqnominadetalle.FieldByName('FNM_TIPO').AsInteger;
      fnmvalorperiodo := sqnominadetalle.FieldByName('FNM_VALORPERIODO').AsCurrency;
      fnmvalordefault := sqnominadetalle.FieldByName('FNM_VALORDEFECTO').AsCurrency;
      fnmdescripcion := sqnominadetalle.FieldByName('FNM_DESCRIPCIONPERIODO').AsString;
      with sqverificardetalle do
      begin
        close;
        ParamByName('PINTEGRANTE').AsString := cedintegrante;
        ParamByName('PCONSTANTE').AsString := codconstante;
        ExecSQL;
        close;
      end;
      // ShowMessage('Net');
      sqnominadetalle.Next;
    end;
  end;
Si sigue siente un tiempo lógico, prueba agregando le update.
Código Delphi [-]
with sqnominadetalle do
  begin
    close;
    SQL.Clear;
    SQL.Add('SELECT * FROM a2NominaDetalle');
    ExecSQL;
    sqnominadetalle.First;
    while not sqnominadetalle.Eof do
    begin
      Log(sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString);
      
      cedintegrante := sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString;
      codconstante := sqnominadetalle.FieldByName('FNM_CONSTANTE').AsString;
      fnmtipo := sqnominadetalle.FieldByName('FNM_TIPO').AsInteger;
      fnmvalorperiodo := sqnominadetalle.FieldByName('FNM_VALORPERIODO').AsCurrency;
      fnmvalordefault := sqnominadetalle.FieldByName('FNM_VALORDEFECTO').AsCurrency;
      fnmdescripcion := sqnominadetalle.FieldByName('FNM_DESCRIPCIONPERIODO').AsString;
      with sqverificardetalle do
      begin
        close;
        ParamByName('PINTEGRANTE').AsString := cedintegrante;
        ParamByName('PCONSTANTE').AsString := codconstante;
        ExecSQL;

        if not sqverificardetalle.IsEmpty then
        begin
          with squpdatenomina do
          begin
            ParamByName('PTIPO').AsInteger := fnmtipo;
            ParamByName('PCONSTANTE').AsString := codconstante;
            ParamByName('PINTEGRANTE').AsString := cedintegrante;
            ParamByName('PVALOR1').AsCurrency := fnmvalordefault;
            ParamByName('PVALOR2').AsCurrency := fnmvalorperiodo;
            ParamByName('PPERIODO').AsString := fnmdescripcion;
            ExecSQL;
            close;
          end
        end;

        close;
      end;
      // ShowMessage('Net');
      sqnominadetalle.Next;
    end;
  end;
Si todo está en un tiempo lógico, el problema estará en el INSERT o en UPDATE final que haces.

Finalmente, trata de traerte todo lo que necesites en el primer SELECT.
Con algo así solo deberás ver si el campo existe_integrante contiene algo o es nulo/cero y te ahorras un SQL por cada vuelta de bucle.

Código SQL [-]
select n.*,
       /* Esta parte sería lo que contiene sqverificardetalle */
       (select first 1 integrante
        from detalle
        where
        integrante = n.fnm_integrante and
        constante = n.fnm_cosntante) as existe_integrante
from a2nominadetalle n

webmasterplc 03-11-2022 13:06:33

Agradecido, hoy me voy a poner a resolver esto y les comento

webmasterplc 04-11-2022 11:17:30

Buenas Tomando la Recomendación de Todos he ido probando, al hacer el log me di cuenta que perdía tiempo en la consulta para verificar el detalle para lo cual en vez de hacerlo tome la recomendación de Casimiro Notevi
Código Delphi [-]
  
select * from tabla1;
while not tabla1.eof  
  try
    update table 2...
  except
    insert into tabla 2...
  end;
  table1.next
end;i
y usando el log que me recomendó duilioisola pude ver lo que tardaba en cada registro en mi ultima prueba tardo 48 minutos 78.648 registros creo que estaría bien dentro de los tiempos o por lo menos se me han mejorado los tiempo considerando que antes duraba 20 min con 120 registros y por tratarse de una base de datos como dbbisam

mi Codigo
Código Delphi [-]
   while not sqnominadetalle.Eof do
                                      begin

                                      cedintegrante:=sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString;
                                      codconstante:=sqnominadetalle.FieldByName('FNM_CONSTANTE').AsString;
                                      fnmtipo:=sqnominadetalle.FieldByName('FNM_TIPO').AsInteger;
                                      fnmvalorperiodo:=sqnominadetalle.FieldByName('FNM_VALORPERIODO').AsCurrency;
                                      fnmvalordefault:=sqnominadetalle.FieldByName('FNM_VALORDEFECTO').AsCurrency;
                                      fnmdescripcion:=sqnominadetalle.FieldByName('FNM_DESCRIPCIONPERIODO').AsString;

                                      try

                                                         with squpdatenomina do
                                                         begin
                                                            ParamByName('PTIPO').AsInteger:=fnmtipo;
                                                            ParamByName('PCONSTANTE').AsString:=codconstante;
                                                            ParamByName('PINTEGRANTE').AsString:=cedintegrante;
                                                            ParamByName('PVALOR1').AsCurrency:= fnmvalordefault;
                                                            ParamByName('PVALOR2').AsCurrency:=fnmvalorperiodo;
                                                            ParamByName('PPERIODO').AsString:=fnmdescripcion;
                                                            ExecSQL;
                                                            Close;
                                                         end;
        
 Log(sqnominadetalle.FieldByName('FNM_INTEGRANTE').AsString+sqnominadetalle.FieldByName('FNM_CONSTANT  E').AsString);
                                      except
                                                              with dbtsdetallenomina do
                                                               begin

                                                                tablename:='a2NominaDetalle';
                                                                Open;
                                                                Insert;
                                                                Append;
                                                                FieldByName('FNM_TIPO').AsInteger:=fnmtipo;
                                                                FieldByName('FNM_CONSTANTE').AsString:=codconstante;
                                                                FieldByName('FNM_INTEGRANTE').AsString:=cedintegrante;
                                                                FieldByName('FNM_VALORDEFECTO').AsCurrency:= fnmvalordefault;
                                                                FieldByName('FNM_VALORPERIODO').AsCurrency:=fnmvalorperiodo;
                                                                FieldByName('FNM_DESCRIPCIONPERIODO').AsString:=fnmdescripcion;
                                                                Post;
                                                                Close;

                                              Close;
                                              end;

                                      end;
                                      sqnominadetalle.Next;
                                      end;

duilioisola 04-11-2022 11:53:10

¿Has comprobado que entra alguna vez a la parte except?

Código Delphi [-]
select * from tabla1;
while not tabla1.eof  
  try
    update table 2...
  except
    Log('INSERT')
    insert into tabla 2...
  end;
  table1.next
end;

Según tengo entendido, si un update no "toca" ningún registro no falla.

mamcx 04-11-2022 14:24:07

Cita:

Empezado por webmasterplc (Mensaje 548971)
y usando el log que me recomendó duilioisola pude ver lo que tardaba en cada registro en mi ultima prueba tardo 48 minutos 78.648 registros creo que estaría bien dentro de los tiempos o por lo menos se me han mejorado los tiempo considerando que antes duraba 20 min con 120 registros y por tratarse de una base de datos como dbbisam

Esto es lo que no cuadra. Como te va a gastar 20 min por tan poco? Yo he hecho cargas de *gigabytes* en ese tiempo.

Mi app principal carga cientos de miles de registros en como 2-3 minutos, y eso contando las tardanzas de viajar por internet.

Y tengo un cliente contra dbisam. Lo único que se me ocurre es que te falta poner un indice.

Pero igual, haciendo todo en memoria y guardando debería no tomar mas de un par de segundos.

Casimiro Notevi 04-11-2022 18:11:48

Es así, eso debería tardar unos segundos, como mucho.

webmasterplc 04-11-2022 19:58:23

Cita:

Empezado por mamcx (Mensaje 548975)
Pero igual, haciendo todo en memoria y guardando debería no tomar mas de un par de segundos.

NO Tengo ni Idea e como hacer los update en memoria

mamcx 04-11-2022 22:42:08

Cita:

Empezado por webmasterplc (Mensaje 548981)
NO Tengo ni Idea e como hacer los update en memoria

Como te había explicado antes, con mas comentarios:

Cita:

Empezado por mamcx (Mensaje 548856)
Código Delphi [-]

// aqui cargas todo en memoria
mi_origen: TClientDataSet := SELECT id FROM db1.Customer 
mi_destino: TClientDataSet := SELECT * FROM db2.Customer

for row in mi_destino
begin
   // Acá resuelves todo en memoria.
   if row.id in mi_origen 
   begin
   // Existe, actualiza
  end else begin
  //No existe, inserta
  end;
end

// Con los datos resueltos, vuelcas todo:

mi_destino.save

Asi debería ser muy rapido, mas que hacer un select en cada ciclo.


webmasterplc 05-11-2022 01:21:07

Cloque un índice y bajo a los 5 minutos aunque por tratarse de dbisam creo que es un tiempo aceptable


La franja horaria es GMT +2. Ahora son las 12:13:33.

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