2012-09-27 5 views
2

Dans notre application au niveau de la base de données, j'ai une table appelée "Factures dans la facturation du schéma" et "Billing_History".SQL Insert/Update/Delete Trigger Efficiency

Le déclencheur indiqué se trouve dans la table Acomptes du schéma de facturation. Cela se produit chaque fois qu'un enregistrement est inséré/mis à jour dans le schéma de facturation. Il est également écrit dans le fichier historique.

Si l'enregistrement est supprimé de la table de facturation, il est écrit dans la table d'historique avec un indicateur "Supprimé" = true.

Je pense que le « If Not exists (Select * from Inséré) est en train de tuer ma performance comme plus de disques sont ajoutés.

est-il un plus effecient était d'écrire ce déclencheur?

Create TRIGGER [Billing].[Installments_InsertDeleteUpdate_History] 
ON [Billing].[Installments] 
AFTER INSERT, DELETE, UPDATE 
AS BEGIN 
Insert Into Billing_History.Installments 
    Select *, GetDate(), 0 From Inserted 

If Not Exists (Select * From Inserted) 
    Insert Into Billing_History.Installments 
     Select *, GetDate(), 1 From Deleted 

SET NOCOUNT ON; 

-- Insert statements for trigger here 

FIN

+0

Suggérez que vous ajoutiez un tag pour ce RDBMS que vous utilisez. – Smandoli

+0

'Si non existant (Select * from Inserted)' ne détruira pas votre performance mais vous pouvez le remplacer par un contrôle 'IF @@ ROWCOUNT> 0' pour la même sémantique. –

+1

Sélectionnez * dans une insertion est une pratique extrêmement pauvre. – HLGEM

Répondre

1

Je dirais que la forme de déclenchement que vous avez est la plus performante, compte tenu des tâches requises. Il n'y a vraiment pas de meilleurs moyens d'atteindre le même résultat d'audit.

La réponse ici serait d'accord Creating audit triggers in SQL Server et voici un long discussion sur la performance des solutions d'audit.

Votre situation est légèrement différente, car vous ne voulez PAS réellement la table supprimée (originale) dans les situations de mise à jour, d'où l'IF.

+0

Merci pour tous les commentaires. À ce stade, je ne pense pas qu'il y ait suffisamment de preuves convaincantes pour modifier/supprimer le déclencheur. Je vais chercher d'autres endroits pour le gain de performance. – AWeim

0

Créer un déclencheur pour INSERTs et UPDATEs et une seconde pour DELETE. Ensuite, vous ne devez pas utiliser une instruction IF et une requête lente pour vérifier où se connecter.

Du point de vue de la conception, voyez si vous pouvez éliminer les déclencheurs. Ils sont un gâchis.

+0

Le 'IF EXISTS (...)' n'est pas une requête lente. Si le PO rencontre des problèmes de performances, je suggère qu'ils regardent ailleurs que cette déclaration. –

+0

@MartinSmith Je pense que vous avez raison. Cela étant dit, il est toujours logique d'utiliser plusieurs déclencheurs pour éliminer les FI inutiles, IMO. –

0

Eh bien vous pouvez faire ce simple changement:

Create TRIGGER [Billing].[Installments_InsertDeleteUpdate_History] 
ON [Billing].[Installments] 
AFTER INSERT, DELETE, UPDATE 
AS BEGIN 

If Not Exists (Select * From Inserted) 
    Insert Into Billing_History.Installments 
     Select *, GetDate(), 1 From Deleted 
ELSE 
    Insert Into Billing_History.Installments 
     Select *, GetDate(), 0 From Inserted 

SET NOCOUNT ON; 

-- Insert statements for trigger here 

Ce qui est logiquement plus efficace, mais que ce soit physiquement plus est une question performante ouverte. Si c'est en fait plus rapide, ce ne sera certainement pas beaucoup.