Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Busqueda de registro lenta (https://www.clubdelphi.com/foros/showthread.php?t=78957)

jafera 30-05-2012 13:13:44

Busqueda de registro lenta
 
A ver si alguien me puede echar un cable.

Ejecuto el código siguiente con un doble clik y cada x veces, no tiene una cadencia fija, se congelan los formularios uno encima del otro tardando más de un minuto en mostrar el resultado.

Código Delphi [-]
 
procedure TF_Parcs.JvDBGrid1DblClick(Sender: TObject);
var cod:Integer;
begin
        cod:= Camions_ParcID.Value;
        if not Assigned(F_Camions) then
        begin
                Buscar_Camio.Close;
                Buscar_Camio.UnPrepare;
                Buscar_Camio.SQL.Text:='SELECT ID FROM BOM0001 WHERE ID ='+ IntToStr(cod);
                Buscar_Camio.Prepare;
                Buscar_Camio.Open;
                F_Camions:=TF_Camions.Create(nil);
                F_ModulDades.Camions.Locate('ID',Buscar_CamioID.Value,[]);
        end
        else
        begin
                Buscar_Camio.Close;
                Buscar_Camio.UnPrepare;
                Buscar_Camio.SQL.Text:='SELECT ID FROM BOM0001 WHERE ID ='+ IntToStr(cod);
                Buscar_Camio.Prepare;
                Buscar_Camio.Open;
                F_ModulDades.Camions.Locate('ID',Buscar_CamioID.Value,[]);
                F_Camions.BringToFront;
        end;
end;

Esto es en D6 y FB 1.5

Saludos

Josep

xomen 30-05-2012 17:20:32

Cita:

Empezado por jafera (Mensaje 433766)
A ver si alguien me puede echar un cable.

Ejecuto el código siguiente con un doble clik y cada x veces, no tiene una cadencia fija, se congelan los formularios uno encima del otro tardando más de un minuto en mostrar el resultado.

Código Delphi [-]
 
procedure TF_Parcs.JvDBGrid1DblClick(Sender: TObject);
var cod:Integer;
begin
        cod:= Camions_ParcID.Value;
        if not Assigned(F_Camions) then
        begin
                Buscar_Camio.Close;
                Buscar_Camio.UnPrepare;
                Buscar_Camio.SQL.Text:='SELECT ID FROM BOM0001 WHERE ID ='+ IntToStr(cod);
                Buscar_Camio.Prepare;
                Buscar_Camio.Open;
                F_Camions:=TF_Camions.Create(nil);
                F_ModulDades.Camions.Locate('ID',Buscar_CamioID.Value,[]);
        end
        else
        begin
                Buscar_Camio.Close;
                Buscar_Camio.UnPrepare;
                Buscar_Camio.SQL.Text:='SELECT ID FROM BOM0001 WHERE ID ='+ IntToStr(cod);
                Buscar_Camio.Prepare;
                Buscar_Camio.Open;
                F_ModulDades.Camions.Locate('ID',Buscar_CamioID.Value,[]);
                F_Camions.BringToFront;
        end;
end;

Esto es en D6 y FB 1.5

Saludos

Josep

Si tu base de datos esta muy pesada o tiene muchos registros debe ser por eso que tarda podrías ayudarle un poco
siendo mas especifico en la query o tal vez reindexando la base de datos. revisa tus formas pueda ser que este algo mal programado
si puedes proporcionar mas datos para poder ayudarte. Espero te sirva de algo saludos

ecfisa 30-05-2012 17:24:42

Hola Josep.

Hace la prueba de este modo:
Código Delphi [-]
procedure TF_Parcs.JvDBGrid1DblClick(Sender: TObject);
begin
  Buscar_Camio.Close;
  Buscar_Camio.SQL.Text:='SELECT ID FROM BOM0001 WHERE ID = :COD');
  Buscar_Camio.ParamByName('COD').AsInteger:= Camions_ParcID.AsInteger;
  Buscar_Camio.Open;
  F_ModulDades.Camions.Locate('ID', Buscar_CamioID.Value, []);
  if not Assigned(F_Camions) then
     F_Camions:=TF_Camions.Create(nil);
  else
    F_Camions.BringToFront;
end;

Saludos.

roman 30-05-2012 18:00:09

Desde luego, el código es mucho más claro como lo pone ecfisa, aunque no creo que influya mucho en la velocidad. Por otra parte, hay algo muy raro en lo que haces:

Código Delphi [-]
Buscar_Camio.SQL.Text:='SELECT ID FROM BOM0001 WHERE ID = :COD');
Buscar_Camio.ParamByName('COD').AsInteger:= Camions_ParcID.AsInteger;

¿Qué sentido tiene esta consulta? Estás buscando el ID de un registro siendo que ya conoces de antemano el ID (se lo pasas como parámetro). ¡Mejor te ahorras la consulta!

// Saludos

jafera 30-05-2012 18:14:39

Gracias por las respuestas.

No es un problema de velocidad realmente, lo que me pasa es que de vez en cuando al hacer el doble click se quedan los formularios congelados uno encima del otro y no puedo hacer nada más que esperar a que se acabe el proceso.
He probado con puntos de interrupción y ver que pasa pero no consigo aislar la linea que se bloquea.
La base tiene solo 1500 registros, una nimiedad para un locate.
El campo ID de la tabla está como PK, todo lo demás son consultas normales.
Sigo investigando, aunque cualquier ayudita se agradece.

Saludos

Josep

ecfisa 30-05-2012 18:30:38

Hola.

En realidad, lo que me llevó a pensar en una posible demora con los forms (y reorganizar el código) fueron las líneas:
Código Delphi [-]
    ...
    F_Camions:=TF_Camions.Create(nil);
    F_ModulDades.Camions.Locate('ID',Buscar_CamioID.Value,[]);
    ...
Donde primero se crea el form y luego se posiciona con Locate, pero viendo ahora que son muy pocos registros, no sé...

Y no había prestado atención a lo que observó roman, tiene razón; la consulta puede omitirse.

Saludos.

jafera 30-05-2012 18:54:05

Gracias.

Yo habia pensado en lo de la consulta para acotar el locate, pues así lo entendí en alguno de los hilos leidos.

El problema persiste y debe ser en la creación del form o algo así ya que como ha dicho antes se produce esporadicamente y sin un patrón fijo.

Si coloco un punto de interrupción en el doble click pasa por todas las lineas correctamente, no se donde más puedo mirar

Saludos

Josep

jafera 30-05-2012 19:13:11

Podria ser que el error estuviera en este prodedimiento?

He intentado ejecutar con f7 y cada vez que entra en el begin, si no se cumple nunguno de los dos id salta al end final y allí se queda el cursor, hago click en el formulario y vuelve al begin, end y así sin parar.

Código Delphi [-]
 
procedure TF_Camions.JvDBGrid2DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
begin
        If F_ModulDades.Camions_AuxACTUAL.Value = 'N' then
        begin
                JVDBGrid2.Canvas.Brush.Color := clMoneyGreen;
                JVDBGrid2.DefaultDrawColumnCell(rect,DataCol,Column,State);
        end;
        if DataCol = 4 then
        begin
                if Pos('X', F_ModulDades.Camions_AuxCODI_CAMIO.Text ) > 0 then
                begin
                        TDrawGrid(sender).Canvas.Font.Color:= clRed;
                        TDrawGrid(Sender).Canvas.Brush.Color:=clYellow;
                        TdbGrid(sender).DefaultDrawColumnCell(Rect, Datacol, Column, State);
                end;
        end;
end;

ecfisa 30-05-2012 21:19:14

Hola jafera.

Cita:

Podria ser que el error estuviera en este prodedimiento?
No conozco el componente JvDBGrid, pero sinceramente no lo creo. Lo único que podría tardar un poco es la función Pos si se aplicase sobre un campo de texto extensísimo, pero por el nombre pareciera ser un código...

Ese comportamiento ¿ Sucede solamente en esa parte de la aplicación ?

Saludos.

jafera 31-05-2012 12:29:47

Buenos días.

Efectivamente Ecfisa, el comportamiento erroneo es solo en esta parte del programa, aunque lo que me hace perder el norte es que este fallo no se produzca siempre sinó aleatoriamente. Con las investigaciones es casi seguro que el error no está en el doble click.

Puede que sea en el form create, form show o algo así, a lo que llegué más cerca de reproducir el error fue en el código que pasé ayer, ya que después de entrar en el begin, el cursor se clavaba en el end y no salía de allí hasta que clicaba en el formulario y a continuación presionaba F9

Gracias

Josep

Chris 31-05-2012 17:10:28

Hola Jafera y todos los compañero del Club!

Te recomiendo que desactives/quites (comentes) la línea que utiliza Locate. Luego has nuevamente las pruebas.

Realmente, Locate es una función muy lenta y consume y desperdicia demasiados recursos si utilizas un DB en red tipo Firebird. Locate solo debería de utilizarse para grupos de datos muy pequeños. Un grupo de 1,500 registros no es precisamente pequeño, más si éstos deben ser transportados por la red.

Otro problema que podría estar empeorando el uso de Locate, es que estás utilizando objetos para los campos. Por ejemplo: "Buscar_CamioID", "Camions_ParcID". Estos objetos deben ser actualizados cada vez que se cambia el cursor, lo que origina un gran consumo de recurso. Además, no sabemos si su implementación interna tenga problemas, cómo una fuga de memoria por ejemplo. Mejor utiliza algo más eficiente cómo por ejemplo: "MiTabla.FieldByName('id')".

Me gustaría saber que base de datos utilizas.

Si encuentras que Locate es el problema, entonces sería oportuno que empieces a pensar en otra arquitectura para conseguir lo que quieres. No esperes una respuesta a: "Cómo hacer más rápido a Locate" porque realmente, Locate no puede ser más rápido. Algo más rápido que Locate, es algo que no sea Locate.

Saludos!

jafera 31-05-2012 18:06:03

Gracias Chris.

Como puse en mi primer post uso Delphi 6 y Firebird 1.5 (de momento), digo de momento ya que quiero migrar a 2.5 pero como uso el ordenador del trabajo y el de casa a la vez y en el trabajo tenemos 1.5, no puedo cambiarme hasta que no actualizemos a 2.5.

Este programa no usa una red, se utiliza en máquina local, todo en el disco C.

Como dije, en las pruebas que hice ayer se quedaba bloqueado en el JvGrid2DrawColumnCell, entraba en el begin y se quedaba en el end sin pasar de ahí (usando F7).

Saludos

roman 31-05-2012 18:11:49

Tratar de concluir algo en cuanto al rendimiento a partir de depurar un evento de redibujado como lo es el DrawColumnCell es sumamente difícil ya que la misma depuración incide sobre las veces que se genera el evento.

Haz la prueba que menciona Chris.

// Saludos

jafera 31-05-2012 18:43:19

Ok, pero si comento el locate, como hago para que me muestre el registro?

Saludos

Edito:
He comentado la linea locate.
El resultado es que cada vez que hago un doble click va al primer registro, en 20 click ni un fallo.
He vuelto a activar esta linea y a la segunda ha fallado

Josep

ecfisa 31-05-2012 19:43:49

Hola.

Si, realmente la función Locate no es ninguna maravilla, pero aún así sigo pensando que el problema se está ocasionando en otro lado.

Acabo de reproducir la situación utilizando un TIBDataSet con Locate sobre un sobre una tabla de 15.698 pacientes y no demora siquiera dos segundos en posicionar, abrir el nuevo form y mostrar los datos. Y aunque el tiempo pudiera incrementarse de acuerdo a la potencia del equipo, eso está muy alejado del congelamiento de las pantallas que habla jafera.

Por otro lado me llama la atención que el comportamiento sea errático. Si fuera ocasionado por la lentitud de un método, procedimiento o función, la situación tendría que ser fácilmente reproducible.

Saludos.

Casimiro Notevi 31-05-2012 20:49:58

Vamos a tener que ver todo el código :)

jafera 31-05-2012 22:13:55

Buenas a todos.

Referente a ver todo el código, por mi no hay problema sólo que hay unas cuantas líneas y no todo falla (por suerte).

Si alguien quiere hacer un teamwiever conmigo, pues aquí estoy dispuesto.

Sigo investigando

Josep

Chris 31-05-2012 22:23:34

Cita:

Empezado por ecfisa (Mensaje 433976)
Acabo de reproducir la situación utilizando un [i]Por otro lado me llama la atención que el comportamiento sea errático. Si fuera ocasionado por la lentitud de un método, procedimiento o función, la situación tendría que ser fácilmente reproducible.

Intenta volver hacer la prueba creando objetos para cada uno de los campos en la tabla, a cómo nuestro compañero está haciendo. Ése escenario sería más fiel al del compañero.

Saludos.

ecfisa 31-05-2012 23:06:37

Hola Chris.

Lo que sucede es que, cuando hice el comentario en el mensaje #15, consideré que jafera ya había aplicado las sugerencias echas y aún así seguía teniendo el mismo problema.

Saludos.


La franja horaria es GMT +2. Ahora son las 02:45: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