Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-01-2009
RaulChemical RaulChemical is offline
Miembro
 
Registrado: jul 2003
Ubicación: Madrid
Posts: 59
Poder: 21
RaulChemical Va por buen camino
Acelerar inserciones masivas en Firebird

Buenas!
Os cuento el problema que tengo:

Necesitamos acelerar la inserción en tablas en Firebird (2.1).
Usamos los componentes FIBPlus (6.9).

Al realizar el proceso de inserción masiva, usamos un TpFIBScripter en el que añadimos las inserts y una vez relleno, ejecutamos el script. Al lanzarlo, el FBServer se come prácticamente el 100% de la máquina (windows) y tarda en torno a 20 segundos en insertar 10.000 líneas. Este proceso está dentro de un bucle y se ejecuta este proceso entre 10 y 15 veces (en total 100mil o 150mil registros).
20 seg cada inserción masiva x 10 = 200 seg (más de 3 min).

Necesitamos acelerar este proceso.

Hemos probado a cambiar el tamaño del caché. Por defecto trae el valor DefaultDbCachePages = 2048 (8Mb). Cambiándolo a 20480 (80Mb) y no hemos conseguido cambios. Cambiándolo a 204800 (800Mb) suelta un error del tamaño de lectura del caché.

Sabéis si existe algún otro truco para hacer este proceso más rápido?

Muchas gracias por todo.
__________________
ash nazg durbatulûk
ash nazg gimbatul
ash nazg thrakatulûk
agh burzum-ishi krimpatul
Responder Con Cita
  #2  
Antiguo 20-01-2009
Avatar de RolphyReyes
RolphyReyes RolphyReyes is offline
Miembro
 
Registrado: ago 2004
Ubicación: Santo Domingo
Posts: 285
Poder: 20
RolphyReyes Va por buen camino
Smile

Saludos.

Se me ocurre que puedes desactivar los indices si existen, verificar los triggers que se disparan y ver si se pueden desactivar también.

En cuanto al tamaño PageSize tienes: 1024, 2048, 4096, 8192 y 16384.

No entiendo el porque utilizar el componente TpFIBScripter, si el componente TpFIBDataSet puede realizar el Insert perfectamente.

Tanto el TpFIBDataSet como el TpFIBQuery tiene los siguientes métodos de Batch:
function BatchInput(InputObject: TFIBBatchInputStream) :boolean;
function BatchOutput(OutputObject: TFIBBatchOutputStream):boolean;
procedure BatchInputRawFile(const FileName:string);
procedure BatchOutputRawFile(const FileName:string;Version:integer=1);
procedure BatchToQuery(ToQuery:TFIBQuery; Mappings:TStrings);

Otra cosa que se me ocurre es que podrías hacer Soft Commit cada x cantidad de registro.

Espero haberte ayudado, hasta luego.
__________________
Gracias,
Rolphy Reyes
Responder Con Cita
  #3  
Antiguo 20-01-2009
RaulChemical RaulChemical is offline
Miembro
 
Registrado: jul 2003
Ubicación: Madrid
Posts: 59
Poder: 21
RaulChemical Va por buen camino
Lo que hago es hacer commit cada 10.000 registros.
Relleno un script, lo lanzo al llegar a 10.000, lo limpio y sigo rellenando.

"Soft Commit"?


Voy a probar cambiando el caché a 16384.

Muchas gracias.
__________________
ash nazg durbatulûk
ash nazg gimbatul
ash nazg thrakatulûk
agh burzum-ishi krimpatul
Responder Con Cita
  #4  
Antiguo 20-01-2009
Avatar de RolphyReyes
RolphyReyes RolphyReyes is offline
Miembro
 
Registrado: ago 2004
Ubicación: Santo Domingo
Posts: 285
Poder: 20
RolphyReyes Va por buen camino
Smile

Saludos.

Soft Commit = CommitRetaining.

Realmente sigo sin entender el porque utilizar TpFIBScripter para rellenar y borrar y luego rellenar.....

El TpFIBScripter vendría siendo como la opción Script Execute de IbExpert donde pones el Script del tamaño que sea con las sentencias que sean (DML y DDL) y lo ejecutas de un golpe.

La misma opción tiene la opción, valga la redundancia, de que pones el COMMIT cada x cantidad de registro.

Si pudieras ser más especifico en cuanto a lo que quieres lograr sería un poco más facil para ayudarte.

Hasta luego.
__________________
Gracias,
Rolphy Reyes
Responder Con Cita
  #5  
Antiguo 20-01-2009
RaulChemical RaulChemical is offline
Miembro
 
Registrado: jul 2003
Ubicación: Madrid
Posts: 59
Poder: 21
RaulChemical Va por buen camino
Lo que hace el programa es pasar los datos de una base de datos de un servidor a una base de datos firebird en local (desconozco la razón por la cual se decidió hacer esto).

Sincronizo los datos tabla a tabla.

Una de las tablas es la que me da estos problemas ya que tiene 150.000 registros, el resto no suele tener más de 2.000.

Por cada registro genero una insert que añado en el TpFibScripter.
Cuando he generado 10.000 inserts, ejecuto el script (TpFibScripter.ExecuteScript), lo limpio (TpFibScripter.Clear) y continuo generando inserts hasta EOF de la query del servidor.

Es la ejecución de esos scripts de 10.000 líneas las que tardan 20 segundos cada una.

Espero que con esto, me puedas ayudar.

Muchas gracias.
__________________
ash nazg durbatulûk
ash nazg gimbatul
ash nazg thrakatulûk
agh burzum-ishi krimpatul
Responder Con Cita
  #6  
Antiguo 20-01-2009
Avatar de RolphyReyes
RolphyReyes RolphyReyes is offline
Miembro
 
Registrado: ago 2004
Ubicación: Santo Domingo
Posts: 285
Poder: 20
RolphyReyes Va por buen camino
Exclamation

Saludos.

Ya entiendo la idea, lo que estas haciendo es un "replicador" de datos.

Se me ocurre dos cosas:

1.- Utilizar los métodos que te había mencionado Batchxxx.
2.- Si es una copia tal cual de como esta la BD del Servidor, entonces sería mejor si haces un Backup de la BD y luego un Restore en la PC local.

Otra cosa podría ser que consigas un programa como IBReplicator o similares, que ya están hechos y probados.
__________________
Gracias,
Rolphy Reyes
Responder Con Cita
  #7  
Antiguo 20-01-2009
RaulChemical RaulChemical is offline
Miembro
 
Registrado: jul 2003
Ubicación: Madrid
Posts: 59
Poder: 21
RaulChemical Va por buen camino
El problema es que la base de datos del servidor no es Firebird, es MySQL.

Mi replicador lo que hace es pasar los datos de un lado al otro haciendo insert's.

Voy a probar lo de los Batchxxx.

Muchas gracias.
__________________
ash nazg durbatulûk
ash nazg gimbatul
ash nazg thrakatulûk
agh burzum-ishi krimpatul
Responder Con Cita
  #8  
Antiguo 20-01-2009
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: may 2003
Ubicación: Colombia
Posts: 7.058
Poder: 29
jhonny Va camino a la famajhonny Va camino a la fama
Pregunto por curiosidad, ¿De que manera generas las sentencias "inserts" que traes de la base de datos "origen"?, o mejor... ¿Cual es el mecanismo que usas para ello?
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/
Responder Con Cita
  #9  
Antiguo 20-01-2009
RaulChemical RaulChemical is offline
Miembro
 
Registrado: jul 2003
Ubicación: Madrid
Posts: 59
Poder: 21
RaulChemical Va por buen camino
Tengo un xml donde tengo las tablas a sincronizar, los campos de cada tabla, con su nombre en firebird y su nombre en mysql y el tipo de dato (varchar, integer, timestamp).

Recorro mi lista de tablas. Por cada tabla hago una select de los campos que tiene en el xml y genero la insert con los campos que me trae el xml.
__________________
ash nazg durbatulûk
ash nazg gimbatul
ash nazg thrakatulûk
agh burzum-ishi krimpatul
Responder Con Cita
  #10  
Antiguo 20-01-2009
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: may 2003
Ubicación: Colombia
Posts: 7.058
Poder: 29
jhonny Va camino a la famajhonny Va camino a la fama
Otra solución es que tal vez, te enfoques en optimizar el momento en que creas las sentencias Inserts. Seguramente optimizando la manera como creas estas sentencias (Inserts), podrias mejorar un poco o mucho el tiempo de respuesta total.

Por ejemplo, si haces una especie de concatenación con la función CONCAT de MYSQL para que traiga los Inserts ya "parseados" desde el principio y no tengas que recorrer el XML para generar los Inserts. Tal vez esto te ahorre algo o mucho de tiempo.
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/
Responder Con Cita
  #11  
Antiguo 20-01-2009
RaulChemical RaulChemical is offline
Miembro
 
Registrado: jul 2003
Ubicación: Madrid
Posts: 59
Poder: 21
RaulChemical Va por buen camino
Pues si, la verdad es que tienes razón. Podría quitar algo de tiempo al generar las inserts, pero de todas formas, el cuello de botella lo sigo teniendo al insertar en Firebird.

Lo tendré en cuenta.

Muchas gracias.
__________________
ash nazg durbatulûk
ash nazg gimbatul
ash nazg thrakatulûk
agh burzum-ishi krimpatul
Responder Con Cita
  #12  
Antiguo 20-01-2009
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: may 2003
Ubicación: Colombia
Posts: 7.058
Poder: 29
jhonny Va camino a la famajhonny Va camino a la fama
Cita:
Empezado por RaulChemical Ver Mensaje
Pues si, la verdad es que tienes razón. Podría quitar algo de tiempo al generar las inserts, pero de todas formas, el cuello de botella lo sigo teniendo al insertar en Firebird.

Lo tendré en cuenta.

Muchas gracias.
Bueno, es que es de esperar que al tener cada vez mas registro, mas se van a demorar en insertarse, eso sucedería en cualquier motor y así encuentres la manera de optimizar esta inserción (por ahora) mas adelante volverás a tener el mismo problema.

Lo otro que te sugiero es que filtres y traigas únicamente los registros que han tenido modificaciones o los que son nuevos (Desde la ultima actualización), mas no todos, pues como bien dices se te va creando un "Cuello de botella" bastante estrecho.
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/
Responder Con Cita
  #13  
Antiguo 21-01-2009
Avatar de Chris
[Chris] Chris is offline
Miembro Premium
 
Registrado: abr 2007
Ubicación: Jinotepe, Nicaragua
Posts: 1.678
Poder: 19
Chris Va por buen camino
Estuve leyendo casualmente ayer documentación relacionada a los componentes UIB (Unified Interbase). Parece que para tu tarea son los mas adecuados. Además ellos recomiendan hacer un commit cada 1,000 registros, además utilizar queries con parámetros.

Puedes tomar en cuenta esos detalles, a lo mejor logras una mejoría apreciable.

Saludos.
__________________
Perfil Github - @chrramirez - Delphi Blog - Blog Web
Responder Con Cita
  #14  
Antiguo 21-01-2009
Avatar de Kipow
Kipow Kipow is offline
Miembro
 
Registrado: abr 2006
Ubicación: Guatemala
Posts: 329
Poder: 19
Kipow Va por buen camino
Podrias utilizar algun metodo de replicacion, que se yo en lugar de insertar los 150k registros de un solo podrias hacerlo cada 1000.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
ayuda con inserciones masivas voldemmor Conexión con bases de datos 4 13-03-2008 21:23:05
Problemas Acelerar PHP HomeCinema PHP 1 09-02-2007 11:42:04
Acelerar carga de Delphi mamcx Noticias 4 13-09-2006 00:51:52
Problemas con inserciones masivas gusanita Conexión con bases de datos 2 16-12-2005 06:40:37
Como acelerar el trabajo DBF manuelpr Conexión con bases de datos 3 29-03-2005 19:52:11


La franja horaria es GMT +2. Ahora son las 11:10:16.


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
Copyright 1996-2007 Club Delphi