Una publicación aquí en DBA. StackExchange ( ¿Cuáles son las mejores prácticas para que los desencadenantes mantengan un número de revisión en los registros? ) Ha generado una pregunta interesante (al menos, interesante para mí) con respecto al rendimiento en MySQL.
El contexto es que queremos insertar un registro en una tabla para cada fila que se actualiza. Antes de actualizar la fila, queremos almacenar un valor anterior y luego incrementar una de las columnas (una columna de "versión").
Si hacemos esto dentro de un disparador, funciona bien. Para MySQL, los desencadenantes son fila por fila , por lo que sería una solución fácil. Seleccione los datos actualmente en la tabla, insértelos en la tabla de registro y actualice la columna "versión" en los nuevos datos.
Sin embargo, es posible mover esta lógica a un procedimiento almacenado. Si hace eso, está realizando la inserción y luego incrementa la columna "versión" en la tabla. Todo se establecería en base.
Entonces, cuando se trata de realizar esta inserción, ¿sería más rentable usar el enfoque de procedimiento almacenado basado en conjuntos o un enfoque basado en disparador?
Esta pregunta es para MySQL (ya que tiene disparadores de fila por fila), aunque podría aplicarse a otros DBMS de disparador de fila por fila.
fuente
Respuestas:
En aras de la simplicidad, los disparadores son el camino a seguir para implementar cualquier tipo de seguimiento de los cambios en la base de datos. Sin embargo, debe ser consciente de lo que sucede debajo del capó cuando utiliza disparadores.
De acuerdo con la Programación de procedimientos almacenados de MySQL , la página 256 debajo del encabezado "Trigger Overhead" dice lo siguiente:
En las páginas 529-531 se ofrece una explicación ampliada de la sobrecarga del activador. El punto final de esa sección establece lo siguiente:
No mencionado en el libro es otro factor cuando se utilizan disparadores: cuando se trata del registro de auditoría, tenga en cuenta en qué registra los datos. Digo esto porque si elige iniciar sesión en una tabla MyISAM, cada INSERT en una tabla MyISAM produce un bloqueo completo de la tabla durante el INSERT. Esto puede convertirse en un serio cuello de botella en un entorno de alto tráfico y alta transacción. Además, si el desencadenante está en contra de una tabla InnoDB y registra los cambios en MyISAM desde dentro del desencadenante, esto deshabilitará secretamente el cumplimiento de ACID (es decir, reducirá las transacciones de bloque al comportamiento de confirmación automática), que no se puede revertir.
Al usar disparadores en tablas InnoDB y registrar cambios
De esta manera, los registros de auditoría pueden beneficiarse de COMMIT / ROLLBACK como lo harían las tablas principales.
Con respecto al uso de procedimientos almacenados, debería llamar minuciosamente el procedimiento almacenado en cada punto de DML contra la tabla que se está rastreando. Uno podría fácilmente perderse los cambios de registro frente a decenas de miles de líneas de código de aplicación. Colocar dicho código en un disparador elimina la búsqueda de todas esas declaraciones DML.
CONSIDERACIÓN
Dependiendo de lo complejo que sea el desencadenante, aún puede ser un cuello de botella. Si desea reducir los cuellos de botella en el registro de auditoría, hay algo que puede hacer. Sin embargo, requerirá un pequeño cambio de infraestructura.
Usando hardware básico, cree dos servidores DB más
Esto servirá para reducir la escritura de E / S en la base de datos principal (MD) debido al registro de auditoría. Así es como puedes lograrlo:
Paso 01) Active el registro binario en la base de datos principal.
Paso 02) Con un servidor económico, configure MySQL (misma versión que MD) con el registro binario habilitado. Esto será DM. Configurar la replicación de MD a DM.
Paso 03) Usando un segundo servidor económico, configure MySQL (la misma versión que MD) con el registro binario deshabilitado. Configure cada tabla de auditoría para usar --replicate-do-table . Esto será AU. Configurar la replicación de DM a AU.
Paso 04) mysqldump las estructuras de la tabla de MD y cargarlo en DM y AU.
Paso 05) Convierta todas las tablas de auditoría en MD para usar el motor de almacenamiento BLACKHOLE
Paso 06) Convierta todas las tablas en DM y AU para usar el motor de almacenamiento BLACKHOLE
Paso 07) Convierta todas las tablas de auditoría en AU para usar el motor de almacenamiento MyISAM
Cuando termine
Lo que esto hace es almacenar información de auditoría en un servidor de base de datos separado y también reducir cualquier degradación de E / S de escritura que normalmente tendría MD.
fuente
Aquí hay un enfoque para realizar esta actualización en masa.
Para este ejemplo
Para crear table_A_Keys2Update haga lo siguiente:
Después de completar table_A_Keys2Update con los identificadores cuyo número de revisión debe incrementarse, realice la siguiente UPDATE JOIN para incrementar el número de revisión de todas las filas cuyo id está en table_A y table_A_Keys2Update:
Esta consulta de una línea puede reemplazar un disparador y un procedimiento almacenado.
Opcionalmente, puede colocar esta consulta en un procedimiento almacenado y llamarla si así lo desea.
fuente