Pregunta

Un post aquí en DBA.StackExchange ( ¿Cuáles son las mejores prácticas para los disparadores para mantener un número de revisión de registros? ) ha dado lugar a una pregunta interesante (al menos, interesante para mí) respecto al rendimiento de MySQL.

El contexto es que queremos insertar un registro en una tabla para cada fila que se actualiza. Antes de que se actualiza la fila, que queremos almacenar fuera de un valor anterior y uno después de la subasta de las columnas (una columna de "versión").

Si no hacemos esto dentro de un disparador, que funciona muy bien. Para MySQL, los factores desencadenantes son fila por fila , por lo que sería una solución fácil. Seleccione los datos actualmente en la tabla, insertarlo en la tabla de registro y la actualización de la columna "versión" en los nuevos datos.

Sin embargo, es posible mover esta lógica a un procedimiento almacenado. Si lo hace, se está realizando la inserción, a continuación, incrementando la columna "versión" en la tabla. Todo el asunto se establece en función.

Por lo tanto, cuando se trata de la realización de este inserto, sería esto con más prestaciones a utilizar el enfoque procedimiento almacenado basado en conjuntos o de un enfoque basado en el gatillo?

Esta pregunta es para MySQL (ya que tiene disparadores fila por fila), aunque podría aplicarse a otros gatillo fila por fila DBMS.

¿Fue útil?

Solución

En aras de la simplicidad, los factores desencadenantes son el camino a seguir para la aplicación de cualquier tipo de seguimiento de los cambios de base de datos. Sin embargo, es necesario estar al tanto de lo que ocurre bajo el capó cuando se utiliza disparadores.

Según MySQL procedimiento almacenado Programación , página 256 debajo de la cabeza "Overhead disparador "dice lo siguiente:

Es importante recordar que, por necesidad, disparadores sobrecargan a la instrucción DML al que se aplican. la cantidad real de sobrecarga dependerá de la naturaleza del gatillo, pero como todos --- MySQL disparadores ejecución para cada fila --- la sobrecarga se puede acumular rápidamente para los estados que procesan un gran número de filas. Debieras por lo tanto, evitar la aparición de sentencias SQL caros o procedimental código en disparadores.

Una explicación ampliada de sobrecarga de disparo se da en las páginas 529-531. El punto conclulding de esa sección establece lo siguiente:

La lección aquí es la siguiente: puesto que el código se ejecutará una vez el gatillo para cada fila afectada por una sentencia DML, el gatillo puede fácilmente convertido en el factor más importante en el rendimiento de LMD. Código dentro de la cuerpo necesita disparador para que lo más ligero posible y - en particular - las sentencias SQL en el gatillo deben ser apoyados por índices siempre que sea posible.

No se menciona en el libro es otro de los factores desencadenantes cuando se utiliza: Cuando se trata de registro de auditoría, por favor, ser conscientes de lo que se conecte datos. Digo esto porque si decide conectarse a una tabla MyISAM, cada una inserción en una tabla MyISAM produce un bloqueo de tabla completa durante la inserción. Esto puede convertirse en un serio cuello de botella en un entorno de alta de transacciones de alto tráfico. Además, si el gatillo está en contra de una tabla InnoDB y que se conecte cambios en MyISAM desde dentro del disparador, esto será el cumplimiento de ACID en secreto con discapacidad (es decir, reducir las transacciones de bloques para el comportamiento de confirmación automática), que se no puede ser revertido.

Al utilizar disparadores de las tablas InnoDB y el registro de cambios

  • En la tabla que se conecte a InnoDB es también
  • Ha compromiso automático desactivado
  • configuración Usted START TRANSACTION ... COMMIT / ROLLBACK bloques a fondo

De este modo, los registros de auditoría pueden beneficiarse de COMMIT / ROLLBACK al igual que las tablas principales.

En cuanto a uso de procedimientos almacenados, que tendría que llamar minuciosamente el procedimiento almacenado en cada punto de DML contra la mesa está realizando el seguimiento. Uno podría fácilmente cambios en el registro de menos en la cara de decenas de miles de líneas de código de la aplicación. La colocación de dicho código en un gatillo elimina la búsqueda de todas las declaraciones de esos DML.

CAVEAT

En función de la complejidad del disparador es, todavía 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, se requerirá un poco de cambio de infraestructura.

Uso de hardware común, crear dos más servidores de base de datos

Este servidor para reducir la escritura de E / S en la base de datos principal (MD) debido al registro de auditoría. Aquí es cómo se puede lograr que:

Paso 01) Activar el registro binario en la base de datos principal.

Paso 02) El uso de un servidor de bajo costo, MySQL configuración (misma versión que MD) con el registro binario activado. Esta será la DM. replicación de configuración desde MD a DM.

Paso 03) El uso de un segundo servidor de bajo costo, MySQL configuración (misma versión que MD) con el registro binario deshabilitado. Configuración de cada tabla de auditoría de usar --replicate-do-mesa . Esta será la UA. configuración replication de DM a la UA.

Paso 04) mysqldump las estructuras de tabla de MD y cargarlo en DM y AU.

Paso 05) Convertir todas las tablas de auditoría en MD utilizar el motor de almacenamiento InnoDB

Paso 06) Convertir todas las tablas de MS y la UA para utilizar el motor de almacenamiento InnoDB

Paso 07) Convertir todas las tablas de auditoría en la UA para utilizar el motor de almacenamiento MyISAM

Cuando se hace

  • DM replicará de MD y grabar cosas en su log binario solamente
  • - réplica-do- tabla de filtros en todas las tablas de auditoría, la UA se replicará de DM

Lo que esto hace es almacenar información de auditoría en un servidor de base de datos separada y también a reducir la degradación de escritura de E / S que normalmente tendría MD.

Otros consejos

Aquí es un enfoque para realizar esta actualización de forma masiva.

Para este ejemplo

  • TABLE_A tiene Primario CLAVE
  • Se crea una tabla llamada table_A_Keys2Update con sólo ID como PRIMARY KEY
  • rellena table_A_Keys2Update withs los identificadores de TABLE_A sabes debe ser actualizado

Para crear table_A_Keys2Update hacer lo siguiente:

CREATE TABLE table_A_Keys2Update SELECT id FROM table_A;
ALTER TABLE table_A_Keys2Update ADD PRIMARY KEY (id);

Después de llenar table_A_Keys2Update con los ID cuyas necesidades número de revisión se incremente, realice la siguiente actualización JOIN al número de revisión incremento de todas las filas cuyo ID es tanto TABLE_A y table_A_Keys2Update:

UPDATE table_A A INNER JOIN table_A_Keys2Update B USING (id)
SET A.revision = A.revision + 1;

Esta línea de una consulta puede sustituir a un gatillo y un procedimiento almacenado.

Opcionalmente, se puede colocar éste consulta en un procedimiento almacenado y llamarlo si así lo desea.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a dba.stackexchange
scroll top