
Demasiadas conexiones (MySQL con dbExpress)
#1
Escrito 22 octubre 2010 - 04:35
Estoy ejecutando un proceso de inserción masivo a una base de datos MySQL, sin embargo, dicho proceso se detiene debido a que se generaron mas conexiones de las que puede soportar y muestra un bello mensaje de error
"To many Connections"
Este proceso crea los componentes dbExpress en "runtime" y en el administrador de MySQL se ven las conexiones en estado "Sleep".
¿ Hay alguna forma de cerrar las conexiones una vez que termina su proceso ?
SAlud OS
#2
Escrito 22 octubre 2010 - 05:14
#3
Escrito 22 octubre 2010 - 05:17
#4
Escrito 22 octubre 2010 - 05:27
¿Porque abres varias conexiones a la vez? ... si se puede preguntar
Pues no abro varias conexiones, el proceso es el siguiente:
//Abro la conexión while not TablaX.EoF do begin //Genero 5 procesos de insertar TablaX.Next; end; //Cierro la conexión
Salud OS
#5
Escrito 22 octubre 2010 - 05:28
¿Y que tal un Pool Connection?
http://edn.embarcade...m/article/30027
Saludos!
Interesante artículo, voy a darle una estudiada a fondo, gracias amigo

Salud OS
#6
Escrito 22 octubre 2010 - 05:55
Si ese es el caso yo usaría un solo insert multiple por cada tabla, he comprobado que el rendimiento aumenta radicalmente de esta manera.
Algo así:
with TStringList.Create do try while not TablaX.EoF do begin Add(Format('(%s,%s),',[TablaX.FieldValues['Campo1'],TablaX.FieldValues['Campo1']])); TablaX.Next; end; ConsultaSQL:= 'insert into tablaY (Campo1,Campo2) values ' + Text; // Quitamos la coma final Delete(ConsultaSQL,Length(ConsultaSQL),1); finally Free; end; // Ahora solo tenemos que ejecutar la consulta para insertar todos los registros de una sola vez
#7
Escrito 22 octubre 2010 - 09:21
Por tu código intuyo que estas leyendo datos de una tabla e insertándolo en otras 5, realizando un insert por cada registro.
Si ese es el caso yo usaría un solo insert multiple por cada tabla, he comprobado que el rendimiento aumenta radicalmente de esta manera.
En realidad es una migración de ciertos datos de muchas tablas de Firebird a muchas tablas de MySQL, son 5 procesos que están involucrados.
Esto sólo lo tengo que hacer una vez y bueno, me fuí por la fácil, ahora el proceso es como sigue:
while not TablaX.EoF do begin //Creo la conexión //Abro la conexión //Genero 5 procesos de insertar //Cierro la conexión //Destruyo la conexión TablaX.Next; end;
Se que esto suena a chapuza y seguramente no es lo más ortodoxo, pero al final me funcionó y ya no genera conexiones a lo bestia, de cualquier forma lo que me importaba (y urgía, cosa rara



Gracias por el apoyo

Salud OS
#8
Escrito 26 octubre 2010 - 12:29
Continuando con mi pequeño problema, me surge la duda de como esperar a que termine una consulta SQL ya que es lo (que pienso) que está dejando conexiones dormidas (sleeps).
Alguien sabe como hacer eso ?
Lo de los semaforos, es muy interesante, pero no le entendí mucho

Salud OS
#9
Escrito 26 octubre 2010 - 07:34
Aquí te pongo unas recomendaciones del gran Ian Marteens par la inserción masiva de registros en la vieja Interbase, puede servirte de guía y encontrar alguna analogía con MySql.
1 ¡Nunca utilice una instrucción generada “al vuelo”! Por el contrario, encierre la sentencia de
inserción dentro de un procedimiento almacenado, y utilice este procedimiento.
2 No olvide preparar el procedimiento antes de comenzar la ejecución. Ya he mencionado que la
preparación de consultas y procedimientos en DB Express no queda muy clara que digamos,
pero merece la pena que haga pruebas en este sentido.
3 Un error común es olvidarse de las transacciones... con lo que casi siempre se logra que cada
inserción vaya protegida por su propia transacción individual. Si es posible, agrupe todas las inserciones
en una misma transacción. Si esta transacción global consumiese demasiado tiempo,
podría fragmentarla en transacciones de menor tamaño: cada 100 registros, por ejemplo.
4 Puede crear más de un procedimiento almacenado de inserción. Además del procedimiento que
inserta un registro, definiríamos un procedimiento que insertase dos registros. Es más barato
ejecutar una vez este segundo procedimiento que dos veces el procedimiento original. Puede
intentar crear versiones del procedimiento que inserten grupos más grandes con una sola operación.
Por supuesto, debe comprobar hasta qué punto rebaja los tiempos de ejecución con esta
técnica para no llegar a exageraciones contraproducentes.
5 Por último, la técnica que logra las mejoras más dramáticas tiene que ver directamente con la
configuración de la base de datos. En concreto, puede que convenga desactivar la opción Forced
Writes de la base de datos, que controla la existencia de una caché de escritura:
Normalmente, los administradores activan esta opción para evitar problemas con cuelgues de software
y fallos de alimentación. Si la inserción masiva es una opción poco frecuente, puede solicitar
que el administrador deshabilite temporalmente las grabaciones forzadas al disco. En el caso en que
usted mismo actúe de administración, tómese la justicia por su mano...