PDA

Ver la Versión Completa : ¿Unir varios disparadores en uno sólo mejora el desempeño de las operaciones?


Al González
21-03-2013, 02:50:55
Hola amigos.

En Firebird 1.5 tengo una tabla con alrededor de 50 campos, 20 disparadores (la mayoría Before / After Insert y Update) y 600 mil registros. Cada mes debe realizarse una operación sobre la misma que agrega y / o modifica unos 20 mil registros. Dependiendo de varios factores, la operación puede durar desde unos minutos hasta varias horas (conlleva muchos cálculos y validaciones y no todo se hace en la base de datos). Tiempos que son aceptables, pero que he conseguido reducirlos retocando varias partes de la aplicación y de la base de datos. Durante esta tarea se me ocurrió la idea de que, probablemente, si uniera varios de esos disparadores en uno sólo el proceso podría demorar un poco menos.

Mi duda concreta y la razón por la cual inicio este hilo es preguntarles si, en su experiencia o conocimiento de Firebird u otras bases de datos, tiene algún beneficio de velocidad significativo sustituir, digamos, varios disparadores Before Insert de una tabla como esta por un sólo disparador Before Insert que haga las mismas tareas. O si, por el contrario, el procesamiento se volvería más lento.

No quiero comenzar a modificar los disparadores de la tabla sin antes tener la certeza de si sería una buena idea. Y hacer pruebas con una tabla o base de datos paralela me da dolor de espalda apenas pensarlo (sí que se vuelve uno flojo con los años :p).

Si alguien de Club Delphi ya ha pasado por experimentar de esa manera con los disparadores, bienvenido sea su testimonio. Mientras voy a seguir con otras cosas de la chamba.

De antemano gracias. :)

Delphius
21-03-2013, 03:11:30
No he tenido la dicha de pasar por la experiencia que comentas Al pero me llama la atención tu duda.
Creo, en mi más humilde entender, que quizá sea posible (y hasta mejor) directamente definir un procedimiento almacenado. Pregunta: ¿Es necesario que tales acciones se lleven a cabo ante cada before/after delete/insert/update?
Quizá se mejore las cosas si en lugar de estar disparando una y otra vez por cada registro, se manda a ejecutar un procedimiento almacenado que tome estas acciones y las "agrupe" en una misma rutina. Como si fuera un proceso que se dispara por lotes y a ciertos intervalos regulares.

Como en muchas cosas, depende, depende... A veces es posible optar por un procedimiento almacenado, en otras la más viable pasa por medio de disparadores.

No es pecado que un triggers de esos que tienes invoque y delege el trabajo en un procedimiento almacenado ;)

Saludos,

Casimiro Notevi
21-03-2013, 10:18:00
Mi experiencia en casos similares es que la diferencia de tiempo no se nota apenas, pero eso sí, usando varios por separado ( ... position 0, ... position 1, etc.) luego es más cómodo e intuitivo el mantenimiento de los mismos.
Aunque no sé qué tipo de procesos realizas, me ha llamado mucho la atención de que tarde "entre unos minutos y varias horas" porque no me he encontrado nunca ningún proceso que tarde más de unos segundos (en BD de muchos gigas y con tablas de decenas de millones de registros: históricos, logs, etc. )
Supongo que harás algún tipo de proceso que nunca me ha tocado hacer.

lbuelvas
21-03-2013, 15:31:36
Hola, creo que la demora es debido al volúmen de registros en una sola operación, sin embargo revisate tal vez este por algún lado alguna o algunas consultas internas que hacen los triggers que generen planes tipo NATURAL (en los que se recorre toda una tabla) y estén afectando el rendimiento y se hacen visibles por el volúmen de datos.

De otro lado si estas mandando los datos directamente desde el lado cliente podrias cambiarlo por hacer el montaje a una tabla temporal de firebird, hacerle una preparación a esos datos para facilitarle la vida a los triggers y utilizar un procedimiento almacenado para efectuar el cargue de datos.

mamcx
21-03-2013, 17:55:23
Pues lo 1ero que se hace (en vez de programar al estilo vudu) es determinar cual es el proceso mas lento, y *por que*.

Al González
21-03-2013, 18:19:34
Mi experiencia en casos similares es que la diferencia de tiempo no se nota apenas [...]
Viniendo de Casimiro, creo que me quedaré con esta respuesta. Dejaré los disparadores individuales. ^\||/

[...] me ha llamado mucho la atención de que tarde "entre unos minutos y varias horas" [...]
Bueno, como dije, eso es dependiendo de varios factores, y uno de esos factores es que el usuario elija sólo un sector de la ciudad o bien toda la ciudad. Y como ya había mencionado, no todo el proceso se realiza sobre la base de datos. Perdón por no haber sido más claro. :o

Reitero, conseguí reducir los tiempos a algo que se considera aceptable, pero tenía esa duda sobre los disparadores. ;)

De todas formas el hilo queda abierto al tema concreto que se anuncia en el título, gracias.

fjcg02
22-03-2013, 10:30:24
hola Al,
salvando las distancias, puede que no esté de más que eches un vistazo a este link

The examples below are the results of months of efforts trying to perform a large financial analysis on a large database (> 4Gb) within reasonable timings. The real breakthrough came with the introduction of the RDB$DB_KEY. In addition to enormous speed increase, it minimized the need for indexing, thus making both development and implementation both safer and easier.

http://web.archive.org/web/20090103043321/http://www.cvalde.net/document/practical_use_of_the_rdb.htm

http://web.archive.org/web/20090104045149/http://www.cvalde.net/ibDocumentation.htm

Igual no tiene demasiado que ver con tu problema, pero te puede dar alguna pista.

Un saludo

Al González
22-03-2013, 18:13:08
Gracias Javier, esos artículos se ven sumamente interesantes. :)