|
Personalmente, en vista de todos los indicios, sigo opinando que la causa más probable de todos estos problemas, es que no has creado los índices adecuados para que el optimizador de consultas interno del motor de interbase, pueda ejecutar de forma eficiente las consultas involucradas dentro de los procedimientos almacenados.
Es muy distinto ejecutar una consulta, pudiendo aprovechar un índice para su ejecución, que hacerlo sin la ayuda de un índice. En el primer caso la localización de los registros involucrados es practicamente instantánea, puesto que la localización de un registro dentro de un árbol B-Tree balanceado solo requiere unas pocas lecturas de disco. En cambio si no se puede aprovechar ningún índice, hay que localizar los registros involucrados por fuerza bruta, leyendo todos los registros de la tabla, y ordenandolos en memória si el resultado está ordenado. Como puedes imaginar en este segundo caso, el consumo de memória y de CPU puede ser desorbitado, no es nada extraño ver consultas que tardan 1 hora en ejecutarse, y que después de crear un índice conveniente, pasan a ejecutars en décimas de segundo.
NOTA : En muchos casos, el índice para optimizar consultas complejas, y subconsultas, tiene que ser múltiple, es decir que conste de varios campos (como el ejemplo que propuse).
Deberías hacer unas cuantas comprobaciones muy sencillas. Por ejemplo, sustituir las UDFS por operaciones simples dentro de las consultas. Aunque evidentemente el resultado no será el mismo, el tiempo que tarden en ejecutarse los procedimientos sin UDFs te indicará claramente si el problema está en las UDFs o en los propios procedimientos.
Respecto a la memória, a mi no me parece tan raro que no se devuelva. Es algo bastante habitual ver sistemas en que una vez ampliado un buffer de memória, no la devuelven hasta finalizar el proceso, aunque ya no sea necesaria esa memória. Simplemente se la reservan por si acaso vuelve a ser necesaria.
Quizá puedas encontrar una función del API que te devuelva la memória, pero mientras tanto deberías probar la opción de cerrar la conexión, puesto que no necesitas más de 30 segundos para probarlo. Además es una solución que puede no gustar (evidentemente no es nada elegante), pero que funciona. Si no puedes cerrar la conexión porqué tienes datasets abiertos y no quieres que se cierren, entonces puedes tener simplemente dos conexiones. Una conexión para el funcionamiento normal de la aplicación, y otra para ejecutar estos procedimientos almacenados, que se abre antes de ejecutarlos y se cierra después.
Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
|