Question

Un message ici DBA.StackExchange ( Quelles sont les meilleures pratiques pour les déclencheurs de maintenir un numéro de révision sur les dossiers? ) a donné naissance à une question intéressante (au moins, intéressant pour moi) en ce qui concerne les performances de MySQL.

Le contexte est que nous voulons insérer un enregistrement dans une table pour chaque ligne qui est mis à jour. Avant la ligne est mis à jour, nous voulons stocker hors une valeur précédente et un incrément des colonnes (une colonne « version »).

Si nous le faisons à l'intérieur d'un déclencheur, il fonctionne bien. Pour MySQL, les déclencheurs sont ligne par ligne , il serait donc une solution facile. Sélectionnez les données actuellement dans le tableau, l'insérer dans la table d'enregistrement et la mise à jour la colonne « version » dans les nouvelles données.

Cependant, il est possible de déplacer cette logique à une procédure stockée. Si vous faites cela, vous effectuez l'insert, puis incrémenter la colonne « version » du tableau. La chose entière serait fonction.

Alors, quand il vient d'effectuer cet insert, ce serait plus performant d'utiliser l'approche de procédure stockée ensemble ou une approche basée sur le déclencheur?

Cette question est pour MySQL (car il a des déclencheurs ligne par ligne), bien qu'il puisse appliquer à d'autres déclencheur ligne par ligne DBMS.

Était-ce utile?

La solution

Par souci de simplicité, les déclencheurs sont la voie à suivre pour mettre en œuvre toute sorte de suivi des changements de base de données. Cependant, vous devez être au courant de ce qui se passe sous le capot lorsque vous utilisez les déclencheurs.

Selon MySQL stockées Procédure de programmation, à la page 256 sous la tête « Trigger Frais généraux »dit le texte suivant:

  

Il est important de se rappeler que, par nécessité, les déclencheurs ajoutent les frais généraux   la déclaration de DML auquel ils se rapportent. le montant réel des frais généraux   dépendra de la nature de la détente, mais --- comme tout MySQL   déclencheurs exécutent POUR CHAQUE LIGNE --- les frais généraux peut accumuler rapidement   des déclarations qui traitent un grand nombre de lignes. Vous devriez   donc éviter de placer des instructions SQL coûteuses ou de procédure   code dans les déclencheurs.

Une explication approfondie des frais généraux de déclenchement est donnée aux pages 529-531. Le point conclulding de cette section stipule ce qui suit:

  

La leçon ici est la suivante: puisque le code de déclenchement exécutera une fois   pour chaque ligne affectée par une instruction DML, la gâchette peut facilement   devenir le facteur le plus important dans la performance DML. Code à l'intérieur du   corps a besoin déclenchement d'être aussi léger que possible et -   notamment - toutes les instructions SQL dans le déclencheur doivent être pris en charge par   index chaque fois que possible.

Non mentionné dans le livre est un autre facteur lors de l'utilisation des déclencheurs: En ce qui concerne l'enregistrement d'audit, s'il vous plaît être conscient de ce que vous ouvrez une session de données dans. Je dis cela parce si vous choisissez de vous connecter à une table MyISAM, chaque insertion dans une table MyISAM produit un verrou de table complet pendant la INSERT. Cela peut devenir un sérieux goulot d'étranglement dans un trafic important, l'environnement de transaction élevés. En outre, si le déclencheur est contre une table InnoDB et vous enregistrer les modifications à MyISAM à partir du déclencheur, cela conformité ACID secrètement désactivé (à savoir, réduire les transactions de bloc à comportement autocommit), qui ne peut être annulée.

Lors de l'utilisation des déclencheurs sur les tables InnoDB et les changements se connecter

  • Le tableau que vous vous connectez à InnoDB est aussi
  • Vous avez autocommit désactivé
  • Configuration Vous commencez TRANSACTION ... COMMIT / ROLLBACK blocs soigneusement

De cette façon, les journaux d'audit peuvent bénéficier de COMMIT / ROLLBACK comme le ferait des tableaux principaux.

En ce qui concerne l'utilisation des procédures stockées, vous devez appeler laborieusement la procédure stockée à chaque point de DML sur la table étant suivi. On pourrait facilement passer à côté des changements d'exploitation forestière face à des dizaines de milliers de lignes de code d'application. Placer un tel code dans un déclencheur trouver élimine toutes ces déclarations DML.

CAVEAT

Selon la complexité de la gâchette est, il peut encore être un goulot d'étranglement. Si vous voulez réduire les goulots d'étranglement dans la journalisation d'audit, il y a quelque chose que vous pouvez faire. Toutefois, il faudra un peu de changement d'infrastructure.

Utilisation du matériel de base, créez deux serveurs DB

Ce serveur volonté de réduire écriture d'E / S sur la base de données principale (MD) en raison de l'enregistrement d'audit. Voici comment vous pouvez l'accomplir:

Étape 01) Activer l'enregistrement binaire dans la base de données principale.

Étape 02) Utilisation d'un serveur peu coûteux, MySQL de configuration (même version que MD) avec la journalisation binaire activée. Ce sera DM. la réplication d'installation de MD à DM.

Étape 03) L'utilisation d'un second serveur peu coûteux, MySQL de configuration (même version que MD) avec l'enregistrement binaire désactivé. Configurez chaque table de vérification à utiliser --replicate-do table . Ce sera l'UA. configuration replication de DM à l'UA.

Étape 04) mysqldump les structures de table de MD et le charger dans DM et AU.

Étape 05) Convertir toutes les tables d'audit dans MD pour utiliser le moteur de stockage BLACKHOLE

Étape 06) Convertir toutes les tables de DM et de l'UA d'utiliser le moteur de stockage BLACKHOLE

Étape 07) Convertir toutes les tables d'audit dans l'Union africaine à utiliser le moteur MyISAM

Lorsque vous avez terminé

  • DM répliquera de MD et des trucs d'enregistrement dans son journal binaire uniquement
  • Avec - replicate-do-table de filtre sur toutes les tables d'audit, l'UA va répliquer de DM

Qu'est-ce que cela fait est d'information d'audit magasin sur un serveur DB séparé et également réduire toute dégradation I / O écriture que MD aurait normalement.

Autres conseils

Voici une approche pour effectuer cette mise à jour en vrac.

Pour cet exemple,

  • TABLE_A a id PRIMARY KEY
  • Vous créez une table appelée table_A_Keys2Update avec id comme clé primaire
  • Vous Populate table_A_Keys2Update withs ids de TABLE_A vous connaissez doit être mis à jour

Pour créer table_A_Keys2Update procédez comme suit:

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

Une fois que vous remplissez table_A_Keys2Update avec les ids dont les besoins numéro de révision à incrémenter, effectuez les opérations UPDATE suivante JOIN pour le numéro de révision incrément de toutes les lignes dont l'identifiant est à la fois TABLE_A et table_A_Keys2Update:

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

Cette une requête en ligne peut remplacer un déclencheur et une procédure stockée.

En option, vous pouvez placer une requête dans cette une procédure stockée et l'appeler si vous le désirez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top