Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Consume memoria, se porque, pero no se como evitarlo... (https://www.clubdelphi.com/foros/showthread.php?t=24853)

sostro 04-09-2005 23:35:33

Consume memoria, se porque, pero no se como evitarlo...
 
Hola a todos. Gracias por vuestro tiempo.
Explico lo que me ocurre.
Tengo la siguiente función:

Código Delphi [-]
{Leer registro TarifaProducto}
 function TMDatosLocal.LeerRegistroTarifaProducto(Id_TarifaProducto:Integer):TTarifaProducto;
 var
   TarifaProducto:TTarifaProducto;
 begin
   {Consulta}
   with MDatosLocal.IBQTarifaProducto do
   begin
     SQL.Clear;
     SQL.Add('Select * from TarifaProducto Where Id_TarifaProducto=:MiId_TarifaProducto ');
     ParamByName('MiId_TarifaProducto').asInteger:=Id_TarifaProducto;
     Open;
     {Recoger los datos}
     with TarifaProducto do
     begin
       Id_TarifaProducto:=FieldByName('Id_TarifaProducto').asInteger;
       Id_Tarifa:=FieldByName('Id_Tarifa').asInteger;
       Id_Producto:=FieldByName('Id_Producto').asInteger;
       CodigoProducto:=FieldByName('CodigoProducto').asString;
       Nombre:=FieldByName('Nombre').asString;
       CosteFabKg:=FieldByName('CosteFabKg').asFloat;
       BeneficioUD:=FieldByName('BeneficioUD').asFloat;
       KiloUnidad:=FieldByName('KiloUnidad').asFloat;
       Medida:=FieldByName('Medida').asString;
       CosteFabricaMillar:=FieldByName('CosteFabricaMillar').asString;
       CosteDestinoMillar:=FieldByName('CosteDestinoMillar').asString;
       Notas:=FieldByName('Notas').asString;
       Eliminado:=FieldByName('Eliminado').asInteger;
       Orden:=FieldByName('Orden').asInteger;
     end; {with interno}
     Close;
   end; {with externo}
   {Registro}
   EscribirRegistro('Lectura de TarifaProducto ' + IntToStr(TarifaProducto.ID_Tarifa)
     + ' ' + IntToStr(TarifaProducto.ID_Tarifa) + ' Correcta');
   {Devolver TarifaProducto}
   LeerRegistroTarifaProducto:=TarifaProducto;
 end;
Una consulta normal y corriente.
El programa requiere en cierto momentos llamar a esta función unas 20.000 o 30.000 veces "consecutivas". Según se llama a esta función el proceso correspondiente al programa en ejecución devora memoria RAM... hasta que el SO dice basta y en forma de protesta anuncia "out of memory". (Ha llegado a ocupar 500 Mb de RAM el proceso...)
Llevo una serie de horas investigando, y variando el parametro BufferChunks del control IBQTarifaProducto de tipo IBQuery de 1000 (valor predefinido) a 2 la cosa mejora ostensiblemente. Pero por lo que he leido ese valor es el número de registro que almacena el control en cache para evitar sobrecarga del sistema para protegerse en caso de consultas que devuelvan muchos registros; además un consecuencia directa de modificar dicho parametro es que la llamada consecutiva a dicha función se reduce de 120 veces por segundo ( con BufferChuks a 1000) a 15 veces por segundo (con BufferChunks a 2); la consulta se enlentece no poco.
Entiendo que el problema con la memoria es debido a que cada vez que llamo a la función no elimino los datos almacenados anteriormente en el buffer del control IBQuery. Pregunta: ¿como lo hago?. En caso de que mi diagnostico no sea cierto, ¿que hago?.

Un saludo a todos y gracias por todo.

NOTA: Esto me ocurre no sólo con esta consulta, sino con cualquiera que tenga un uso equivalente, así que descarto problemas específicos de esta consulta que elegí para poner un caso práctico.

Saludos...

Casimiro Notevi 05-09-2005 00:35:48

Cita:

Empezado por sostro
Código Delphi [-]
EscribirRegistro('Lectura de TarifaProducto ' + IntToStr(TarifaProducto.ID_Tarifa)
      + ' ' + IntToStr(TarifaProducto.ID_Tarifa) + ' Correcta');
    {Devolver TarifaProducto}
    LeerRegistroTarifaProducto:=TarifaProducto;
  end;

Ese último LeerRegistroTarifaProducto qué es?, una variable?

sostro 05-09-2005 00:41:24

Hola Casimiro. Gracias por tu interés.

Es la devolución de lo buscado en la BD. Es una estructura que devuelvo por ser una función lo que he transquito.

Un saludo.

Crandel 05-09-2005 07:06:59

Cita:

Empezado por Casimiro Notevi
Ese último LeerRegistroTarifaProducto qué es?, una variable?

Hola Casimiro, me sorprendio tu pregunta! pregunta muy básica para alguien con tu experiencia :D.

Bueno siempre se aprende algo nuevo.

Se puede devolver el valor de una función tanto con result como con el nombre de la función.

Cita:

Empezado por sostro
¿que hago?.

Pensandolo ahora encuentro dos posibilidades:

* Podrias usar Prepare y UnPrepare del Query.

* Supongo que estas llamando tantas veces a esta función porque quieres que te obtener los resultados para varios Id_TarifaProducto, porque no haces la consulta para que te devuelta todos los resultados en una sola tabla en vez de un solo resultado por vez.

sostro 05-09-2005 11:03:08

Hola Ángel. Gracias por implicarte.

Pues no puedo hacer una única consulta, pues la demanda de lectura de los registros de esa tabla es impredicible. No es previsible cual será el siguiente registro solicitado a leer. Se requiere la lectura de ese registro, y se ejecuta.
Aunque pudiera hacer una consulta de multiples registros, sólo sería enmascarar el problema, y lo que realmente quiero es terminar de dominar el problema.

Es un programa de uso intensivo y relativamente grande.

Ya había probado el comando Prepare y no funcionó siquiera la lectura.

Un saludo Ángel.

sostro 05-09-2005 11:05:26

Ah, y un dato relevante. No depende del tamaño de lo que se quiera buscar. La basura que me deja en memoria es más o menos del mismo tamaño sin importarle el nº de registros filtrados por la consulta SQL.

Otro dato: Delphi 7 + IBX + Interbase 6.5

Un saludooo

defcon1_es 05-09-2005 12:24:17

Hola,
¿has probado con la propiedad Unidirectional = True de la Query?

Casimiro Notevi 05-09-2005 13:25:38

Cita:

Empezado por Crandel
Hola Casimiro, me sorprendio tu pregunta! pregunta muy básica para alguien con tu experiencia :D.

Precisamente por eso, por la experiencia, porque puedo saber qué es o imaginarme que es eso, se supone, pero siempre pongo en práctica aquello que dice: "de lo que no veas, nada creas... y de lo que veas, sólo la mitad" ;)

Así que si no tienes todo el código para comprobar... es mejor preguntar, por si acaso. Te puedes encontrar con muchas sorpresas.

:)

sostro 05-09-2005 14:15:34

Premio para Defcon1... todos mis problemas han desaparecidos... es la fórmula magistral.


Un saludo a todos, gracias por vuestro tiempo y en especial a Defcon1 (entendereis esta deferencia con él ;-) )

paty_rlopez 17-03-2007 17:52:40

Me perdi en la solucion
 
Hola a todos y disculpen pero ya no entendí. Tengo el mismo problema con el out of memory con un IBQuery y no supe como se arregló, si alguien me puede explicar como se solucionó el problema se lo agradezco mucho.

Lepe 17-03-2007 20:20:28

Según defcon1, dice que es poniendo la propiedad Unidirectional del IbQuery a True.

Pero que conste que lo dice él :D :D , yo simplemente transcribo... que de esto no entiendo y me sorprende la solución :o .

Saludos

paty_rlopez 20-03-2007 16:01:43

Gracias
 
muchas gracias Lepe
No contesté antes porque solo tengo internet en mi trabajo y acabo de llegar de un laaargo fin de semana.
probare lo que dice Defcon1.


La franja horaria es GMT +2. Ahora son las 00:47:59.

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