PDA

Ver la Versión Completa : Query vs. StringList


MaMu
10-03-2008, 20:19:14
Query vs. StringList (matriz)

Si tengo que manejar 2 campos calculados, y en el evento OnCalcField, necesito ubicar un dato proveniente de otro query para realizar ese cálculo...
que es más rapido:

1) Lanzar ese query y ubicar con LOCATE
OtroQuery.Locate('campo',varcampo,[]);
2) Tener ese dato almacenado en un StrinList y recorrerlo hasta encontrarlo

for i:=0 to lista.count-1 do
begin
if lista[i]=varcampo then.... //etc
end;

3) Alguna recomendación o sugerencia que desconozca?

OJO(izquierdo): que el query para calcular los campos viene de una tabla mySQL, pero la tabla con esos campos esta en memoria.
OJO(derecho): más o menos, opero con un promedio de 5000 registros.

Saludos

poliburro
10-03-2008, 20:56:10
El primero es mejor pues explotas las características de búsqueda del componente.


si aún así deseas usar el segundo prueba con esta forma optimizada:

With Lista Do
ShowMessage(Strings[IndexOf(Elemento)]);

MaMu
10-03-2008, 21:01:41
El primero es mejor pues explotas las características de búsqueda del componente.


si aún así deseas usar el segundo prueba con esta forma optimizada:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)
With Lista Do
ShowMessage(Strings[IndexOf(Elemento)]);





Claro, pero con mas de 100 registros ya se hace mas lento, con 5000 ni hablar, y realmente no se como optimizar la situación. En vez de usar una tabla temporal, quizas me convenga usar una tabla mySQL.

MaMu
11-03-2008, 00:30:31
Estaba pensando, por ahi lo que me combiene, es trabajar directamente sobre una tabla mySQL, y evitar el OnCalcField, reemplazando todo el metodo por consultas y subconsultas, usando asignaciones y variables, etc.
Lo que me preocupa es la velocidad del proceso, cargando hasta 10000 registros.
Que diferencia tengo entre usar:

1)

MiQuery.Insert;
try
MiQuery.FieldByName('campo1').AsString:='Pepon';
MiQuery.Post;
except
MiQuery.Cancel;
end;


2)

MiQuery.Close;
MiQuery.SQL.Text:='INSERT INTO tabla...........values('pepon')';
MiQuery.ExecSQL;


Saludos

poliburro
11-03-2008, 00:56:16
Son exactamente lo mismo.

Quiere mejorar el rendimiento?, utiliza entonces procedimientos almancenados.

Al González
11-03-2008, 09:17:57
Algo bueno sería lanzar una sola consulta Select donde cada fila de resultado correspondiera a una fila de la tabla de memoria. Pero claro, esta opción dependería de cómo están relacionados los datos y de si existe alguna condición que pueda aplicarse a la consulta para que arroje las filas tal y como queremos.

Como lo anterior es muy improbable, tener la lista de cadenas parece ser mejor opción, pero ¿cómo sabes qué valores colocar en la lista de cadenas? ¿la tabla de memoria siempre es la misma o presenta un patrón lógico común en cada ocasión que la creas?

Tal vez he comprendido mal, pero me parece que indagando un poco más en tu caso podríamos encontrar una solución eficaz.

Saludos.

Al.

Neftali [Germán.Estévez]
11-03-2008, 10:29:02
La opción de lanzar un LOCATE para cada campo calculado va a ser lenta. En ese caso yo optaría por la búsqueda en la tabla en memoria. De topdas formas no me acaba de quedar clara ninguna de las dos soluciones.

Tal vez no entendí que qué iba la cosa...

ASAPLTDA
11-03-2008, 12:51:49
Hola, creo que la mejor solucion es usar un client data set almacena los datos en momoria pero con las posibilidades de una tabla

Neftali [Germán.Estévez]
11-03-2008, 13:30:17
creo que la mejor solucion es usar un client data set almacena los datos en momoria pero con las posibilidades de una tabla

Pensándolo bien, estoy de acuerdo.
En principio mejor el TClientDataset que el TStringList; La única ventaja de este segundo sería el acceso por Find (que utiliza búsqueda dicotómica) y seguramente será más rápido que el locate (aunque se realice en memoria).

MaMu
11-03-2008, 18:02:49
A ver si entendí la sugerencia:

Lo mejor seria un ClienDataSet, con su Provider apuntado al Query que lanza la consulta a la otra tabla, y localizar el registro usando el método find?

La situación es la siguiente, ya no uso tablas en memoria, opero directamente sobre el mySQL server, donde en un la tabla A, tengo 2 campos calculados, que se calculan en base a los datos de otra tabla.

Saludos

Neftali [Germán.Estévez]
12-03-2008, 11:59:51
La situación es la siguiente, ya no uso tablas en memoria, opero directamente sobre el mySQL server, donde en un la tabla A, tengo 2 campos calculados, que se calculan en base a los datos de otra tabla.

Los datos de esa segunda tabla los cargas en un TClientDataset en lugar de un Dataset normal, y eso provoca que todos los datos de esa segunda tabla se traigan al Cliente (a memoria), de forma que las búsquedas sobre esa segunda tabla no se hacen sobre el servidor de SQL sino sobre los datos que hay en memoria (utilizando un LOCATE, por ejemplos).

Hay que tener en cuenta cómo es de gande esa segunda tabla...

MaMu
13-03-2008, 02:30:53
SOLUCIONADO

Claro, esta muy bien. Lo probé y me funcionó más que bien.

Saludos