Buenas a todos.
Por aqu� ando otra vez.
A ver si me pongo ya en serio sin distracciones con mi amado Object Pascal :)
Un saludo a todos.
P.D.: javivf, te envi� hace tiempo un mail sobre LRUT, lo llegaste a recibir?

Mailing lists / lazarus-es / 2009-03
10 messages · 6 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Buenas a todos.
Por aqu� ando otra vez.
A ver si me pongo ya en serio sin distracciones con mi amado Object Pascal :)
Un saludo a todos.
P.D.: javivf, te envi� hace tiempo un mail sobre LRUT, lo llegaste a recibir?
Buenas lista.
Tengo un problemilla que me trae un pelin perdido. Funcionar funcionar... funciona. Pero me gustar�a optimizarlo si es posible.
El caso es que tengo que importar a una base de datos un fichero de texto plano con lineas del tipo:
A80108#121061411#31/12/2007#00:01:06#1111111#NAT#XX#P#A#MV#0#0#.15
(los # son TABuladores)
En principio, la rutina que os pongo m�s abajo iba bastante bien cuando los ficheros ten�an un tama�o peque�o-mediano... Ahora con 162370 el que menos, la verdad es que se vuelve bastante lento...
Me preguntaba si a vosotros se os ocurrir�a algo para mejorar esto... Gracias!
//******************************************************//
procedure TfrmMain.Importar(ruta_fichero: string);
var
sl, slFila: TStringList;
linea, columna: integer;
begin
sl := TStringList.Create;
slFila := TStringList.Create;
slFila.Delimiter := #9; // TABULADOR
try
// cargo el fichero
sl.LoadFromFile(ruta_fichero);
for linea := 0 to sl.Count - 1 do
begin
// cargo la linea en el stringlist
slFila.DelimitedText := sl[linea];
// aqui ya tengo el slFila "partido" en columnas,
// por lo que puedo acceder a cada campo de la forma:
// campo0 = slFila[0];
// campoX = slFila[X];
//
// y procesar cada linea...
end;
finally
slFila.Free;
sl.Free;
end;
//******************************************************//lazarus en differware.net escribi�:
Seria interesante que cuentes que BD usas , poruqe MySql tiene funciones de importacion directo de texto plano, ahora no lo tengo presente pero si googleas lo encontras seguro. A lo sumo tendrias que cambiar los tabulados por comas.
Ma�ana me fijo en el manual de Mysql como se hace y te lo envio.
Maximiliano escribi�:
Pues la base de datos que uso, por ahora, es MySQL porque ya tengo el servidor instalado, pero no descarto pasarme a Firebird...
En cuanto a importar, el problema es que el fichero no est� limpio, es decir, hay "cabeceras" que debo eliminar y datos que no necesito. Imagina el formato como una factura de tel�fono, y que solo interesan las lineas de llamada que realizas ignorando el resto de datos.
lazarus en differware.net escribi�:
Yo lo que haria, es limpiar el archivo, dejar solo los datos que quiero y hacer un script sql para tirasel� al motor.
Cambiar los tabulados por comas y sabiendo donde va cada dato hacer un insert y eecutar todo el script de una sola vez.
insert into tabla (campo1,campo2,campo3....) values (A80108,121061411,31/12/2007,00:01:06,1111111,NAT,XX,P,A,MV,0,0,.15); insert into tabla (campo1,campo2,campo3....) values (A80108,121061411,31/12/2007,00:01:06,1111111,NAT,XX,P,A,MV,0,0,.15); .
.
.
.
mysql tiene la ventaja de que interpreta los datos y no hace falta la comillas en los campos de texto, pero puede llegar a fallar en firebird, este ultimo si pones todo entre comillas lo convierte al tipo de dato destino
Buenas lista. Tengo un problemilla que me trae un pelin perdido. Funcionar funcionar...…
Hello lazarus,
Tuesday, March 31, 2009, 5:05:54 PM, you wrote:
ldn> En principio, la rutina que os pongo m�s abajo iba bastante bien cuando ldn> los ficheros ten�an un tama�o peque�o-mediano... Ahora con 162370 el que ldn> menos, la verdad es que se vuelve bastante lento...
162000 lineas o bytes ?
ldn> Me preguntaba si a vosotros se os ocurrir�a algo para mejorar esto...
La rutina a mi al menos me parece que no es precisamente el cuello de botella, haz la prueba de procesar los archivos sin el trozo de c�digo que mete los datos en la base y seguro que la diferencia es abismal.
Las bases de datos suelen sufrir mucho con transacciones largas (de muchos registros) as� que si puedes (no necesitas transaccionalidad completa de todos los registros) haz un commit cada X registros.
Otra opci�n ser�a que en vez de meterlos directamente a la base de datos generes un fichero intermedio tipo CSV o similar que puedas importar directamente con alguna utilidad de la base de datos para importaciones masivas de datos.
JoshyFun escribi�:
162000 lineas o bytes ?
Hablo de l�neas.
Uso los componentes Zeos. Y ya que hablas de transacciones, ca� en que siempre hab�a usado "ZConnection.AutoCommit := true". Mi experiencia con programas para varios usuarios es casi nula, y hasta ahora me hab�a ido bien as�. Supongo que de este modo inicia una transaccion por cada INSERT que hago...
Vaya, las pruebas que he hecho haciendo "commits" cada 100 INSERTS no mejora notablemente la velocidad de inserci�n.
He probado con tablas MyISAM e InnoDB, pero tampoco noto mucho la diferencia. Voy a cronometrar el tiempo para que sea algo m�s real y menos subjetivo.
Supongo que me esperaba que fuese m�s r�pido...
Muchas gracias por la ayuda!
Hola!
Usa acceso directo a fichero y la funci�n readline, TStringList funciona bien pero es extremadamente ineficiente para gran acceso a disco de grandes cantidades de l�neas, si lo que quieres es velocidad. Aparte, el Autocommit ponlo a False, si no te hace un Commit tras cada inserci�n, algo tremendamente ineficiente.Pon un commit tras cada 500 l�neas, es lo m�s normal.
Saludos.
JoshyFun escribi�: Hablo de l�neas. Uso los componentes Zeos. Y ya que hablas de…
Hello lazarus,
Wednesday, April 1, 2009, 12:07:25 PM, you wrote:
ldn> JoshyFun escribi�:
> 162000 lineas o bytes ?
ldn> Hablo de l�neas.
Esas son demasiadas lineas para un TStringList, bueno no demasiadas ya que las maneja, pero el consumo de memoria as� como realizar semejante cantidad de GetMem/FreeMem (al menos 3 por linea de texto) complica su gesti�n sobre manera.
Si quieres puedes usar readln sobre un fichero o si quieres usar streams tengo por alg�n sitio un TFileStream con un ReadLine con cach� de prelectura para que la lectura de las lineas sea r�pida, desde luego el consumo de memoria va a bajar de manera sustancial y la velocidad deber�a ser igual o superior.
De todos modos el cuello de botella es la DB. Como ejemplo yo tengo que hacer sobre firebird 1.5 un "select" de unos 200000 registros y actualizar un campo de cada uno a trav�s de programa (no puedo hacerlo con una stored procedure) y la velocidad de actualizaci�n es de unos 1000 por segundo con transacciones de 500 en 500.
Podias usar LOAD DATA una funcion propia del motor Mysql. Tenes dos modos para hacerlo indicandole LOCAL para que te lea tu archivo y lo suba al motor, o sin LOCAl lo cual debe estar el archivo en una ruta del motor y lo levanta solo.
este est� bueno porque acepta tanto bloques con insert o en bruto separado por tabulados.
El unico cuello seria la subida del archivo y la demora se produce en el servidor, el cliente no lo notaria. Inclusive se puede hacer en segundo plano como un servicio que a medida que llegan los archivos los procesa y los mueve a una carpeta de backup.