Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Providers
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 31-05-2014
Avatar de rcarrillom
[rcarrillom] rcarrillom is offline
Miembro Premium
 
Registrado: dic 2004
Ubicación: UK / North Sea / Norway / Golfo de México / Frente a mi Laptop
Posts: 219
Poder: 20
rcarrillom Va por buen camino
Lentitud al leer ClientDataSet.ChangeCount / Delta

Un saludo al foro

Tengo un problema de rendimiento, estoy usando un ClientDataSet (sin estar conectado a un proveedor) al cual le agrego 235,000 registros de un solo golpe, inmediatamente después de terminar las operaciones de insercion, al consultar el valor de ChangeCount, tarda muchisimo tiempo en regresar de la llamada, el mismo problema me da al acceder a la propiedad Delta. Es un bug? Hay un forma mas eficiente de saber solamente si se ha modificado el conjunto de datos sin consultar ChangeCount?

Programo con Delphi XE3 en WinXP Pro.
__________________
eLcHiCoTeMiDo - Rompecorazones profesional
Yo no soy presumido; ¿Pero de qué sirve mi humilde opinión contra la de los espejos?
Salva a un nylon, usa prendas de piel de foca
Responder Con Cita
  #2  
Antiguo 31-05-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
235000 registros de ¿cuántos kbytes cada uno?
Responder Con Cita
  #3  
Antiguo 01-06-2014
Avatar de rcarrillom
[rcarrillom] rcarrillom is offline
Miembro Premium
 
Registrado: dic 2004
Ubicación: UK / North Sea / Norway / Golfo de México / Frente a mi Laptop
Posts: 219
Poder: 20
rcarrillom Va por buen camino
La estructura es, y si no mal recuerdo el tamaño de los datos
ID Integer 2 bytes
Num1 Float 6 bytes
Num2 Float 6 bytes
Num3 Float 6 bytes
Flag String[1]
IsNav Boolean 1 byte
TimeStamp DateTime 6 bytes
Commentarios string[255]
Num4 Integer 2 bytes

285 bytes
__________________
eLcHiCoTeMiDo - Rompecorazones profesional
Yo no soy presumido; ¿Pero de qué sirve mi humilde opinión contra la de los espejos?
Salva a un nylon, usa prendas de piel de foca
Responder Con Cita
  #4  
Antiguo 01-06-2014
Avatar de rcarrillom
[rcarrillom] rcarrillom is offline
Miembro Premium
 
Registrado: dic 2004
Ubicación: UK / North Sea / Norway / Golfo de México / Frente a mi Laptop
Posts: 219
Poder: 20
rcarrillom Va por buen camino
Corrijo lo anterior, considerando que los Int son de 4 bytes y los float de 8 bytes, la suma total para el registro sólo para datos es de 289 bytes, que multiplicados por los 235,000 registros, nos da 67,915,000 bytes en memoria al menos.

El campo Comentarios casi siempre está vacio, de todos estos registros que se insertan, si acaso habrá 200 registros con Comentario de no mas de 50 caracteres de largo.

Sigo sin entender, por qué es tan lento el sólo consultar el valor que regresa ChangeCount? Traté de asignar Delta a la propiedad Data de otro ClientDataSet como método alterno y al momento de hacer la asignacion cds2.Data := cds1.Delta tarda muchisimo tiempo.
__________________
eLcHiCoTeMiDo - Rompecorazones profesional
Yo no soy presumido; ¿Pero de qué sirve mi humilde opinión contra la de los espejos?
Salva a un nylon, usa prendas de piel de foca
Responder Con Cita
  #5  
Antiguo 01-06-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola rcarrillom.

Hice una prueba con un TClientDataSet en memoria cargándolo de forma aleatoria:
Código Delphi [-]
const
  TOTREG = 235000;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  s: array[0..255] of char;
begin
  Randomize;
  FillMemory(@s[0], 255, Byte('-'));
  ClientDataSet1.CreateDataSet;
  ClientDataSet1.Open;
  for i:= 1 to TOTREG do
  begin
    if i mod 1000 = 0 then
      ClientDataSet1.MergeChangeLog;
    ClientDataSet1.Append;
    ClientDataSet1ID.AsInteger:= i;
    ClientDataSet1Num1.AsFloat:= Now;
    ClientDataSet1Num2.AsFloat:= Now;
    ClientDataSet1Num3.AsFloat:= Now;
    ClientDataSet1IsNav.AsBoolean:= Boolean(Random(2));
    ClientDataSet1Flag.AsString:= Char(Random(27)+65);
    ClientDataSet1TimeStamp.AsDateTime:= Now;
    ClientDataSet1Comentarios.AsString:= s;
    ClientDataSet1Num4.AsInteger:= i;
    ClientDataSet1.Post;
  end;
  // Algunas modificiaciones al azar
  for i:= 1 to Random(499)+1 do
  begin
    ClientDataSet1.Locate('ID', Random(TOTREG-1)+1,[]);
    ClientDataSet1.Edit;
    ClientDataSet1Comentarios.AsString:= 'Registro modificado';
    ClientDataSet1.Post;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(Format('Cambios: %d',[ClientDataSet1.ChangeCount]));
end;
Y, si bién la carga inicial tarda dada la cantidad de registros, la respuesta de la propiedad ChangeCount en Button1Click es instantánea.

No sé si se me esté pasando algo por alto o si habré interpretado mal la situación...

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #6  
Antiguo 01-06-2014
Avatar de rcarrillom
[rcarrillom] rcarrillom is offline
Miembro Premium
 
Registrado: dic 2004
Ubicación: UK / North Sea / Norway / Golfo de México / Frente a mi Laptop
Posts: 219
Poder: 20
rcarrillom Va por buen camino
Gracias ecfisa, el escenario general es este, se generan varios archivos Access con la misma estructura por una aplicacion antigua cuyo contenido es un registro de entrada de un puerto serial, y con mi app leo los registros de todos ellos con ADO y los inserto en el ClientDataSet, llegando hasta 300 mil registros.

La estructura la genero de la siguiente manera:
Código Delphi [-]
procedure TdmData.DataModuleCreate(Sender: TObject);
begin
  //Crear la estructura inicial de la BD
  with cdsLog.FieldDefs do begin
    Add('ID'       , ftAutoInc);
    Add('Num1'       , ftFloat);
    Add('Num2'       , ftFloat);
    Add('Num3'       , ftFloat);
    Add('Flag'     , ftString, 1);
    Add('IsNav'    , ftBoolean);
    Add('Comment'  , ftString, 255);
    Add('TimeStamp', ftDateTime);
    Add('Num4', ftInteger);
  end;
  cdsLog.CreateDataSet;
end;

Y para llenarlo con registros, repito el proceso por cada archivo Access que el usuario seleccione con un diálogo Open con seleccion múltiple, como nota, el campo Comment, el 98% de las veces está vacío:

Código Delphi [-]
    ADOTable.Open;
    while not ADOTable.Recordset.EOF do begin
      cdsLog.Append;
      try
        for RecNum := 0 to ADOTable.FieldCount - 1 do
          cdsLog.FieldByName(ADOTable.Fields[RecNum].FieldName).Value := ADOTable.Recordset.Fields[RecNum].Value;
        cdsLog.Post;
      except
        cdsLog.Cancel;
        raise;
      end;
      ADOTable.Recordset.MoveNext;
    end;

Al terminar de anexarlos todos, inmediatamente intento leer ya sea el ChangeCount o el Delta y aqui es donde tarda muchisimo tiempo. Es en este punto donde no entiendo el porqué de la tardanza cuando son 235K registros agregados de un solo golpe, si le agrego 17K la respuesta es casi inmediata.
__________________
eLcHiCoTeMiDo - Rompecorazones profesional
Yo no soy presumido; ¿Pero de qué sirve mi humilde opinión contra la de los espejos?
Salva a un nylon, usa prendas de piel de foca
Responder Con Cita
  #7  
Antiguo 03-06-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola Ricardo.

Es extraño (e interesante) lo que comentas. Veré si encuentro una pista en los fuentes de MIDAS (el motor interno de TClientDataSet). Pero tengo una duda: ¿cuál es la razón por la que necesitas usar ChangeCount?

Para conocer la cantidad total de registros puedes usar la propiedad RecordCount. ChangeCount, en cambio, te dice cuántas modificaciones (altas, bajas y cambios) hay en la "bitácora de cambios" del conjunto de datos respecto a cómo se encontraba antes de comenzar dichas modificaciones. Si éste último dato no fuera necesario en tu caso, te recomendaría poner la propiedad LogChanges en False antes de comenzar las inserciones y usar la clásica propiedad RecordCount. De esa forma el proceso trabajará más rápido.

Un saludo desde el ciber.
Responder Con Cita
  #8  
Antiguo 03-06-2014
Avatar de rcarrillom
[rcarrillom] rcarrillom is offline
Miembro Premium
 
Registrado: dic 2004
Ubicación: UK / North Sea / Norway / Golfo de México / Frente a mi Laptop
Posts: 219
Poder: 20
rcarrillom Va por buen camino
Talking

Gracias Al, mi app es para edicion de datos numéricos que se despliegan en una gráfica, eliminar picos, suavizar puntos, interpolar datos... El ChangeCount es para saber si se ha modificado el conjunto de datos en cualquier momento y para llevar un registro de cambios para un Deshacer. Si hay otra manera de saber simplemente si el conjunto ha cambiando, es bienvenida.

Tengo implementadas las dos formas que mencionas:
1. Si el usuario inicia el proceso desde cero para agregarle archivos existentes, mi app primero crea un dataset vacio y le deja LogChanges = True.
2. Si el usuario inicia el proceso abriendo un archivo existente, entonces hago LogChanges = False y al terminar de cargar lo vuelvo a poner en True. De aqui en adelante se pueden insertar archivos o agregar manualmente registros individuales.

Fusioné 20 archivos que me dan 235K registros y los guardé en uno solo que abro con el método 2 y todo anda perfecto.

Para mí es mas sencillo si lanzo operaciones SQL en memoria sobre los datos del ClientDataSet para actualizaciones en masa a través de componentes de terceros (XQuery) y aprovechando las capacidades del ClientDataSet para deshacer operaciones, no lidiar yo mismo con registros y asignacion de memoria, pero si se me complica el asunto con un simple ChangeCount, tendré que replantear la manera de cómo trabajar los datos y usar estructuras y asignacion de bloques de memoria a la vieja escuela.

Otro problema grave es que al guardar los datos se hace de manera lentisima, al grado que esos 235K registros se guardan en dos minutos, y el programa viejo que los genera los guarda en menos de 5 segundos, este es tema para otro hilo, sera que no sé cómo optimizar estas escrituras.
__________________
eLcHiCoTeMiDo - Rompecorazones profesional
Yo no soy presumido; ¿Pero de qué sirve mi humilde opinión contra la de los espejos?
Salva a un nylon, usa prendas de piel de foca
Responder Con Cita
  #9  
Antiguo 04-06-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola Ricardo.

No tengo Delphi aquí, pero hace un par de horas revisé el funcionamiento de ChangeCount. Cuando lees esa propiedad se ejecuta un proceso que "empaca" cierta información del caché y si este es muy grande, ChangeCount tardará en responder, tal como describes. Tal vez haya otra forma de controlar ese dato.

En los próximos días estudiaré con detenimiento lo que comentas en tu último mensaje, para ver de qué manera se puede solucionar el problema. Mientras tanto, si pudieras ampliar los detalles del caso, mucho mejor, para que todos lo comprendamos bien.

Un cordial saludo.

Al.
Responder Con Cita
  #10  
Antiguo 04-06-2014
Avatar de rcarrillom
[rcarrillom] rcarrillom is offline
Miembro Premium
 
Registrado: dic 2004
Ubicación: UK / North Sea / Norway / Golfo de México / Frente a mi Laptop
Posts: 219
Poder: 20
rcarrillom Va por buen camino
No hay mas detalles Al, para depurar bien, activé la opcion Use debug dcus y no me lleva muy lejos, al llegar a la llamada cdsLog.ChangeCount me lleva a la unit Datasnap.DBClient(2669):
Código Delphi [-]
function TCustomClientDataSet.GetChangeCount: Int64;
begin
  Result := 0;
  if Active then
    Check(FDSBase.GetProp(dspropNOOFCHANGES, @Result));
end;

y ésta llamada me dirije a la unit Datasnap.DSIntf(662);
Código Delphi [-]
    function GetProp(               { Get property }
        eProp       : DSProp;
        piPropValue : Pointer
    ): DBResult; stdcall;

De ahi ya me pide el archivo ds.cpp que no está en mi sistema y ahi ya sale la ventana de CPU. Por el momento he llegado hasta aqui con el código fuente.

Si al CDS le agrego los archivos de un solo golpe el tiempo de consuta a ChangeCount es grande, si lo hago uno por uno, el tiempo se incrementa progresivamente con cada archivo agregado al DS.

Espero que alguien tenga más código fuente que yo, sé que las distintas versiones de Delphi vienen o no con fuentes dependiendo de lo caro que costó
__________________
eLcHiCoTeMiDo - Rompecorazones profesional
Yo no soy presumido; ¿Pero de qué sirve mi humilde opinión contra la de los espejos?
Salva a un nylon, usa prendas de piel de foca
Responder Con Cita
  #11  
Antiguo 05-06-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola Ricardo, encontré algo que puede servir, pero antes quisiera resolver una duda que me surge de lo que has comentado:
Cita:
Empezado por rcarrillom Ver Mensaje
El ChangeCount es para saber si se ha modificado el conjunto de datos en cualquier momento y para llevar un registro de cambios para un Deshacer. Si hay otra manera de saber simplemente si el conjunto ha cambiando, es bienvenida.
Eso me da a entender que no interesa saber la cantidad (el "count") de cambios ocurridos, sino solamente si han ocurrido o no. De ser así, ¿por qué no usas una simple bandera Boolean que pongas en True cuando inicies las operaciones de altas / bajas / cambios, y que pongas en False al hacer cualquier apply/merge?

Por otra parte, si quieres manejar "puntos de restauración" (marcar lo ya hecho para luego regresar), seguramente estás usando también la propiedad SavePoint, eso me parece bien.

En seguida te comento lo que encontré sobre el funcionamiento de la propiedad ChangeCount.

Cita:
Empezado por rcarrillom Ver Mensaje
[...] para depurar bien, activé la opcion Use debug dcus y no me lleva muy lejos, al llegar a la llamada cdsLog.ChangeCount me lleva a la unit Datasnap.DBClient(2669):
Código Delphi [-]
function TCustomClientDataSet.GetChangeCount: Int64;
begin
  Result := 0;
  if Active then
    Check(FDSBase.GetProp(dspropNOOFCHANGES, @Result));
end;

y ésta llamada me dirije a la unit Datasnap.DSIntf(662);
Código Delphi [-]
    function GetProp(               { Get property }
        eProp       : DSProp;
        piPropValue : Pointer
    ): DBResult; stdcall;

De ahi ya me pide el archivo ds.cpp que no está en mi sistema y ahi ya sale la ventana de CPU. Por el momento he llegado hasta aqui con el código fuente. Espero que alguien tenga más código fuente que yo, sé que las distintas versiones de Delphi vienen o no con fuentes dependiendo de lo caro que costó
Yo tengo los fuentes de MIDAS.dll por cortesía de un viejo y gran amigo del club. Gracias a estos archivos he podido hacer algunas mejorillas al TClientDataSet y ayudar a varios colegas con problemas similares al tuyo. Incluso me han servido para explicar a Embarcadero y a la Comunidad la causa de algunas pequeñas fallas. Claro, nunca faltará el zopenco que aun viendo las bondades de aquella acción (no solicitada, por cierto) de mi amigo, venga por aquí a decir que soy un pirata. Admitir que de Embarcadero quisiera comprar más de lo que he comprado, nunca es excusa suficiente para algunos.

En efecto Ricardo, el depurador me lleva también a ese punto del código, y a partir de ahí me veo en la necesidad de examinar el código de MIDAS manualmente. Esta es la parte que hace el cálculo de ChangeCount:
Código:
   case dspropNOOFCHANGES:
      if (piPropValue)
      {
         UINT32 i, iChanges = 0;

         if (pDsLog && pDsLog->iLast)
         {
            DSLOG *pLogNew = new DSLOG(pDsLog->iLast, NULL);

            if (pDsLog->CompactLog(pLogNew) == DBIERR_NONE && pLogNew->iLast > 0)
            {
               iChanges = pLogNew->iLast;
               for (i = 0; i < pLogNew->iLast; i++)
               {
                  LOGENTRY *pLogEntry = &pLogNew->pLogEntries[i];
                  if (pLogEntry->iAttr == dsRecModified)
                  {
                     if (RecsEqual(pLogEntry->iRecNo2, pLogEntry->iRecNo1, TRUE, NULL))
                        iChanges--; // Changes were canceled out
                  }
               }
....
Como podrás ver, hace un "pequeño" for. Pero lo realmente pesado está antes, al llamar al método CompactLog de pDsLog:
Código:
// Compact log, in order to create delta
DBIResult DSLOG::CompactLog(DSLOG *pLogNew)
{
   DBIResult rslt = DBIERR_NONE;
   pBYTE pValid = (pBYTE)DsCalloc(1, iLast +1);
   UINT32 iRecNo, iRecNoOrg;
   UINT32 i, j;

   if (pLogNew == NULL || pValid == NULL)
   {
      rslt = DBIERR_NOMEMORY;
      goto Exit;
   }

   for (i = 0; i < iLast; i++)
   {
...
El cual tiene cerca de 200 líneas de código con muchas validaciones sobre el estado de cada entrada del log. De ahí que demore demasiado cuando ya se han agregado decenas de miles de registros al conjunto de datos.

He de decir que encontré una manera de sacarle la vuelta al problema de la lentitud, pero no me gusta casi nada esta "solución", por dos razones: 1.- Porque no necesariamente se obtiene el mismo valor de la propiedad ChangeCount. Ésta hace un trabajo importante al compactar el registro de cambios, descartando ciertas entradas (como cuando agregas un registro y posteriormente lo eliminas). Lo que obtiene mi solución es la cantidad total de "entradas" en el registro de cambios: el valor de ese contador interno llamado iLast. 2.- Porque no es elegante, ya que implica "jaquear" (¿está bien escrito? ) la estructura de un par de clases contenidas en MIDAS.dll. Esto quiere decir que se deberá probar con mucho cuidado al cambiar de una versión de MIDAS a otra (por lo menos en Delphi 7 y XE2 me funcionó sin problemas).

De todas formas pongo aquí un ejemplo, por si te sirve a ti o a alguien más:
Código Delphi [-]
Type
  TClientDataSetAccess = Class (TClientDataSet);
procedure TForm1.Button1Click(Sender: TObject);
Type
  { Estructura para acceder al campo iLast de la clase interna DSLOG de
    MIDAS (alc_ds.h) }
  TDSLog = Packed Record
    Unused :Array [0..7] Of Byte;  // Primeros campos de la clase

    { NOTA: EntryCount no es necesariamente igual a la propiedad
      ChangeCount; puede ser mayor. }
    EntryCount :Cardinal;  // iLast
  End;

  { Estructura para acceder al campo pDsLog de la clase interna DSBASE de
    MIDAS (alchemy.h) }
  TDSBase = Packed Record
    Unused :Array [0..99] Of Byte;  // Primeros campos de la clase
    DSLog :^TDSLog;  // pDsLog
  End;
Var
  Base :^TDSBase;
  I :Integer;
begin
  // dt1 es un objeto TClientDataSet con dos campos (ID y Name)
  dt1.Close;
  dt1.CreateDataSet;

  For I := 1 To 50000 Do
    dt1.AppendRecord ([I, 'Test']);

  Base := Pointer (TClientDataSetAccess (dt1).DSBase);

  // Ambos mensajes muestran "50000"
  ShowMessage (IntToStr (Base.DSLog.EntryCount));  // Inmediato
  ShowMessage (IntToStr (dt1.ChangeCount));  // Demorado
end;
Ojalá hubiera mayor accesibilidad al interior de MIDAS, como para no tener que hacer este tipo de cosas. Pero como te dije al principio, si sólo necesitas saber si hubo o no hubo cambios, pienso que una simple bandera en tu código Delphi bastaría

Dos cosas más:

Cada vez que haces un Insert/Append/AppendRecord o un Post tradicional, se realizan diversas llamadas a métodos de TDataSet y TClientDataSet. Debes saber que puedes agregar de forma directa los valores a la memoria del ClientDataSet mediante su interfaz DSCursor (es una propiedad protegida, pero perfectamente accesible por derivación de clases), si bien el ahorro de tiempo no va a ser espectacular.

El otro asunto que comentabas, sobre el vaciado de la información a la base de datos, quizá sea más rápido si empleas sentencias SQL directas Insert Into usando tu componente conexión. Aunque también depende de qué componente sea éste y los motores y controladores que estén entre la aplicación y la base de datos.

No más rollo, se terminó la hora de trabajar en lo que me gusta y llegó la hora de trabajar en lo que me da para comer.

Un saludo.

Al González.
Responder Con Cita
  #12  
Antiguo 05-06-2014
Avatar de rcarrillom
[rcarrillom] rcarrillom is offline
Miembro Premium
 
Registrado: dic 2004
Ubicación: UK / North Sea / Norway / Golfo de México / Frente a mi Laptop
Posts: 219
Poder: 20
rcarrillom Va por buen camino
Recórcholis Al, lo que se puede hacer si tienes a la mano los fuentes...

Probaré el código para "hackear", y usaré los eventos para detectar cambios y activar la banderita, habia querido evitarlos para simplicidad de código, ahora me enfrento a la misma lentitud del MergeChangeLog, voy paso a paso resolviendo los problemas... Postearé los resultados.
__________________
eLcHiCoTeMiDo - Rompecorazones profesional
Yo no soy presumido; ¿Pero de qué sirve mi humilde opinión contra la de los espejos?
Salva a un nylon, usa prendas de piel de foca
Responder Con Cita
  #13  
Antiguo 07-06-2014
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola Ricardo, ya nos contarás cómo va.

Cita:
Empezado por ecfisa Ver Mensaje
Código Delphi [-]
const
  TOTREG = 235000;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  s: array[0..255] of char;
begin
  Randomize;
  FillMemory(@s[0], 255, Byte('-'));
  ClientDataSet1.CreateDataSet;
  ClientDataSet1.Open;
  for i:= 1 to TOTREG do
  begin
    if i mod 1000 = 0 then
      ClientDataSet1.MergeChangeLog;
    ClientDataSet1.Append;
...
[...] la respuesta de la propiedad ChangeCount en Button1Click es instantánea.

No sé si se me esté pasando algo por alto [...]
Hola Daniel, disculpa que haya pasado por alto lo que cito de tu comentario. La razón por la cual, en tu caso, ChangeCount responde de forma inmediata, es que por cada mil registros haces una llamada a MergeChangeLog, lo cual limpia la bitácora de cambios, regresando ChangeCount al valor de cero.

Un saludo.
Responder Con Cita
  #14  
Antiguo 07-06-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por Al González Ver Mensaje
Hola Daniel, disculpa que haya pasado por alto lo que cito de tu comentario. La razón por la cual, en tu caso, ChangeCount responde de forma inmediata, es que por cada mil registros haces una llamada a MergeChangeLog, lo cual limpia la bitácora de cambios, regresando ChangeCount al valor de cero.
Hola Alberto.

Si así es, cuando realizo cargas muy pesadas en memoria, acostumbro a usarlo con ese fin. En realidad estuve a punto de proponer el uso al menos luego de la carga de cada archivo Access (suponiendo que no serían significativos los cambios provocados por la carga), pero pensé que luego del mensaje había sido probado sin efecto.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 07-06-2014 a las 05:18:36.
Responder Con Cita
  #15  
Antiguo 11-06-2014
ASAPLTDA ASAPLTDA is offline
Miembro
 
Registrado: jun 2003
Ubicación: COLOMBIA-CALI
Posts: 639
Poder: 21
ASAPLTDA Va por buen camino
Lentitud cambio de control

Hola,
que pasa si: agrego un campo(cambiado) 1 =cambiado 0 sin cambios y este es el indice
cargo los registros viejo sin log de cambio
cargo los registros nuevos sin log de cambios
cuento log registros cambiados usando el indice nuevo por campo cambiado
el usuario cambia un dato entonces cambio el cambio cambiado de 0 a 1 o lo dejo en 1 si fue cambiado previamente
cuanto registros
cuanto demora? la creacion de un indice al vuelo es casi inmmediato
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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Lentitud con ClientDataSet.XMLData en Servicio Datasnap code88 Varios 4 08-02-2013 19:43:07
buscar registros de un ClientDataSet a otro clientDataSet novato_erick Conexión con bases de datos 2 02-02-2013 21:48:09
Lentitud leer .csv ErYcK C++ Builder 23 05-07-2012 23:56:44
Lentitud en la red. Carlos Arevalo Varios 2 09-07-2007 20:04:08
Modificar propiedad Delta de CDS alucardo Conexión con bases de datos 0 04-10-2006 20:36:41


La franja horaria es GMT +2. Ahora son las 21:54:32.


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