Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Tablas TADOTable en memoria (https://www.clubdelphi.com/foros/showthread.php?t=67180)

JF Sebastian 04-04-2010 00:30:06

Tablas TADOTable en memoria
 
El cuello de botella de mi aplicación reside en la lectura de la base de datos. Ésta no ocupa mucho (18 Mb), por lo que desearía cargarla toda en memoria, pero no sé cómo ni si es posible... En principio sólo necesito operaciones de lectura.

Agradecería enormemente alguna sugerencia.

Un saludo

Casimiro Notevi 04-04-2010 01:17:56

Haces una pregunta muy genérica, aclara exactamente qué problema tienes, qué quiéres conseguir, etc.
Y no olvides decir al menos qué base de datos usas ;)

p.d. No te aconsejo leer la guía de estilo porque no ahora no funciona :D, pero puedes leer la otra guía de estilo, la que está en mi firma :)

JF Sebastian 04-04-2010 10:04:21

La base de datos es un .mdb y consta de 7 tablas con MasterFields activado. El tipo de conexión se realiza mediante Microsoft.Jet.OLEDB.4.0. En una parte crítica de la aplicación se necesita realizar una gran cantidad de operaciones de lectura en varias tablas mediante Locate() y FieldByName().
Basicamente existen 3 tablas T1,T2,T3 en las cuales T2.MasterSource apunta a T1 y T3.MasterSource apunta a T2. Estas 3 Tablas tienen definido IndexFieldNames. Lo que trato de optimizar en velocidad es leer el registro Numero n de la tabla T3

Lo que hago actualmente es:

//Localizacion del registro determinado mediante locate. (Lento)
err1 := not T1.Locate('TIPO',TipoPerfilId,[]); //Familia de perfiles
err2 := not T2.Locate('NOMBRE',Perfil,[]); //Grupo de perfiles perteneciente a una familia
err3 := not T3.Locate('NOMBRE', serie1, []); //Perfil perteneciente a un grupo de perfiles


//Posicionamiento del registro dentro de la tabla T3 (Lento)
err := False;
T3.First;
i := 1;
if n>1 then
repeat
i := i+1;
err := T.Eof;
T3.Next;
until (i=n) or err;

//Lectura del registro (Rapido)
Actual(T1,T2,T3,err);


Un saludo y gracias por vuestra paciencia.

Casimiro Notevi 04-04-2010 14:03:41

¿Hay algún motivo para no usar sql?, debería ser más rápido.

JF Sebastian 04-04-2010 14:45:02

Lo que pretendo es eliminar los locates (que tardan mucho). Lamentablemente nunca he trabajado con SQL por lo que no me es familiar.
Desearia probar el rendimiento con SQL, pero no se muy bien como hacerlo :(

Un saludo

Casimiro Notevi 04-04-2010 15:22:15

El compañero Caral escribió un tutorial de cómo hacer un programa con las características técnicas que usa el tuyo, te aconsejo que lo leas, verás que es más sencillo de lo que parece.
Aquí está.

JF Sebastian 04-04-2010 16:36:36

Tenías razón, era más facil de lo que pensaba. Acabo de realizar la prueba con TADOQuery y SQL pero lamentablemente los tiempos son similares a con locate :(.

Supongo que una vez realizada la búsqueda con locate y posicionado el cursor en el registro, la lectura se realiza desde memoria y es muy rápida. Lo costoso resulta realizar la búsqueda en el .mdb que reside en disco.

Lo ideal sería leer toda la base de datos del .mdb y traerla a memoria, esto llevaría tiempo pero se haría una sola vez... Es esto posible??

Un saludo

Casimiro Notevi 04-04-2010 17:13:19

Supongo que si haces un "select * from tutabla" y luego vas al último registro con ".last" ya estaría todo en memoria, pero si son muchos registros no es algo recomendable.
De todas formas, no sé qué estás haciendo exactamente, cómo ni por qué... pero lo "normal" es que una consulta 'select', aunque la tabla tenga millones de registros, debe tardar 'casi' nada, décimas de segundo.
La verdad es que yo de bases .mdb no sé mucho, pero he visto programas de amigos que a pesar de tener muchas tablas y registros, son razonablemente rápidos.
Puede que a partir de mañana recibas más respuestas y ayuda, que ya habrá vuelto mucha gente de estas vacaciones de semana santa :)

Casimiro Notevi 04-04-2010 17:14:15

Cita:

Empezado por JF Sebastian (Mensaje 359167)
[..] Lo costoso resulta realizar la búsqueda en el .mdb que reside en disco.[..]

¿Pero qué es lo que haces en esa búsqueda?

JF Sebastian 04-04-2010 18:27:26

Mi aplicación consiste en el dimensionamiento óptimo de estructuras metálicas formadas por perfiles comerciales (barras). Las dimensiones y características de estos perfiles están en una base de datos .mdb

La base de datos consta de varias tablas, en la primera se almacenan las familias de perfiles disponibles (Laminados, Conformados, Extruidos...) en la segunda se almacenan los nombres de las series de perfiles (IPE, IPN, HEB,...) en la tercera se almacenan los perfiles en si (IPE_100,IPE_120,...), etc. En cada tabla hay campos de relacion ID que empleo para realizar un master-detail de modo que se pueda organizar la información. Además la tercera tabla está ordenada (IndexFieldNames) por un campo específico como puede ser el momento de inercia.

El dimensionamiento se realiza mediante un metodo metaheurístico (HS) de búsqueda, en el que se prueban aleatoriamente diversas configuraciones de perfiles, es normal hacer miles de búsquedas. Por cada búsqueda es preciso efectuar un cálculo algo complejo.

Antes de cada cálculo hay que leer de la base de datos las características de los perfiles de las barras de la estructura en la nueva configuración que selecciona el algoritmo HS (Esta configuración es un vector de enteros de dimensión el número de barras y en el que se almacena un número pseudoaleatorio comprendido entre 1 y el número de perfiles que haya en la tercera tabla ej: IPE_xxx). La estructura a su vez puede tener bastantes barras.

El cálculo esta muy optimizado en velocidad y prácticamente es instantáneo. El cuello de botella reside en leer de la base de datos el perfil aleatorio N dentro de la tercera tabla.

Cada barra tiene asociada una clase con la familia y grupo de perfil (entre otras muchas cosas); no cambian durante el cálculo, lo que varia es la dimensión del perfil.

En las pruebas que he hecho he intentado comentar los locate, first, last, next, prior, recno, etc y de 4 horas de tiempo total de cálculo pasó a 10 minutos.
Comentando además la lectura en sí del registro de la BD, aún más rápido pero no mucho más..

Llevo programando muchos años pero soy bastante profano en bases de datos.:o

Caral 04-04-2010 18:35:55

Hola
Aqui solo veo 2 campos a buscar de 3 tablas.
Tabla T1 Campos TIPO, TipoPerfilId
Tabla T2 Campos NOMBRE, Perfil
Tabla T3 Campos NOMBRE, serie1

No entiendo por que se hace lento el proceso, esta consulta access la hace en fracción de segundos.

Hago consultas con mas tablas y mas campos y no tardan ni un parpadeo.
Para mi que algo estas haciendo mal ya que access no influye en esto.
Otra cosa: Jamas haría que la Tabla completa estuviera en memoria, se alentaría el programa y mucho menos para una simple consulta.
Access tiene un generador de consultas sql, ahí es donde puedes perfeccionar la como la necesites, solo copia y pega esa consulta en delphi y ya.
Saludos

JF Sebastian 04-04-2010 19:12:16

He medido el tiempo que tarda en hacer la consulta con locate y es inferior a 0.05 s
Influye el master-detail en el tiempo de búsqueda con locate??
La tabla T3 tiene sólo unos 5000 registros pero con unos 40 campos

Un saludo

Casimiro Notevi 04-04-2010 19:12:42

Pues sí, haría falta ver cómo lo haces, precisamente el amigo que comenté antes tiene algo parecido pero para una fábrica de muebles de madera y necesita hacer lo mismo que tus cálculos para aprovechar lo mejor posible todo el material.
Y lo hizo en access con sql. Le pregunté y me ha dicho que no tiene ningún problema de velocidad. Lleva funcionando con ese programa desde hace unos 15 años y lo ha ido modificando y ampliando, incluso lo han instalado en otras fábricas de muebles y no se quejan de velocidad.
Así que sería necesario ver tu código, estructuras, etc. para poder echarte una mano.

Casimiro Notevi 04-04-2010 19:13:59

Cita:

Empezado por JF Sebastian (Mensaje 359180)
He medido el tiempo que tarda en hacer la consulta con locate y es inferior a 0.05 s
Influye el master-detail en el tiempo de búsqueda con locate??
La tabla T3 tiene sólo unos 5000 registros pero con unos 40 campos
Un saludo

Entonces, en qué momento es lento?

Caral 04-04-2010 19:15:25

Hola
Segun entiendo el Locate se hace con un AdoTable, es casi un filtro.
Esto se quiera o no trae todos los registros.
Con un AdoQuery el asunto es muy diferente, la velocidad es muy superior.
Saludos

JF Sebastian 04-04-2010 19:37:08

Cita:

Empezado por Casimiro Notevi (Mensaje 359182)
Entonces, en qué momento es lento?

Cuando en la tabla T3 hay unos cientos de registros activos por el master/detail
Cuando hay 20 registros tarda 7 minutos en realizar el cálculo completo
Cuando hay 200 registros tarda más de 120 minutos
Siendo en ambos casos la misma estructura y el mismo número de iteraciones, todo igual, solo variando el tipo de perfil a buscar entre el número indicado arriba (20 y 200)

JF Sebastian 04-04-2010 19:41:44

Cita:

Empezado por Caral (Mensaje 359184)
Hola
Segun entiendo el Locate se hace con un AdoTable, es casi un filtro.
Esto se quiera o no trae todos los registros.
Con un AdoQuery el asunto es muy diferente, la velocidad es muy superior.
Saludos

El problema es que necesito situar el cursor de la base de datos en el registro para poder leer todos los campos, son como ya he dicho unos 40.
Esto lo hago con locate.
He intentado hacerlo con AdoQuery, pero como necesito leer todos los campos tarda practicamente los mismo.

Por cierto, he tenido problemas para localizar un campo integer con locate, ¿Sólo busca textos?:confused:

Casimiro Notevi 04-04-2010 20:30:41

Si te digo la verdad... no entiendo la situación, dices que tarda 120 minutos en hacer qué?, en hacer un cálculo (o un millón de cálculos), en recorrer 200 registros (pero cuántas veces), y el cálculo ese cuánto tarda, cada uno?.

JF Sebastian 05-04-2010 21:33:15

Gracias por vuestras respuestas. :)

Al final he creado una clase que contiene para cada barra todos los perfiles de esa serie con un array of array dinámico.
El rendimiento en velocidad es unas 10 veces superior al de acceso a la base de datos. Como el cálculo es muy intesivo, merece la pena...

Un saludo


La franja horaria es GMT +2. Ahora son las 16:59:39.

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