Posted on Dez 19, 2005 von in SQL Server

Tips und Tricks, die die Performance von Trigger erhöhen können:

Die Zeit, die ein Trigger zur Ausführung benötigt, ist eine Funktion der Anzahl der innerhalb des Triggers referenzierten Tabellen und der Anzahl der vom Trigger Code betroffenen Zeilen. Daher sollte man stets bestrebt sein, die Anzahl der im Trigger involvierten Tabellen und die Anzahl der betroffenen Zeilen zu minimieren.

Zusätzlich sollte der Code eines Triggers auf ein Minimum reduziert werden, um Overhead zu vermeiden. Dies ist wichtig, da Trigger typischerweise durch INSERT's, UPDATE's und DELETE's ausgelöst werden, die in OLTP Applikation häufig vorkommen. Je mehr Code in einem Trigger ausgeführt werden muß, umso langsamer ist jedes INSERT, UPDATE und DELETE, das stattfindet.

*****

Falls der Trigger eine WHERE Klausel beinhaltet, sollte man nicht vergessen, einen geeigneten Index zu erstellen, der verwendet werden kann. WHERE Klauseln, die sich in Triggern verstecken, werden leicht übersehen, aber wie jedes andere SELECT Statement können auch sie signifikant durch einen geeigneten Index beschleunigt werden.
Ein Weg um dies zu testen ist, den Trigger Code im Query Analyzer laufen zu lassen und den daraus resultierenden Ausführungsplan zu untersuchen. Dadurch kann man sehr schnell feststellen, ob man einen geeigneten Index hinzufügen muß oder nicht.

*****

Hat man ein INSERT, UPDATE oder DELETE Statement daß länger zu benötigen scheint als angemessen, sollte man überprüfen, ob ein Trigger auf der beteiligten Tabelle definiert ist. Das Performance Problem, das man beobachtet, könnte sehr wohl auf den Trigger zurückzuführen zu sein, nicht auf das DML Statement selber.
Man sollte nicht vergessen, Trigger Code genauso zu optimieren wie man es mit jedem anderen Code auch macht. Aufgrund der Tatsache, daß Trigger Code im Hintergrund läuft, scheinen viele Leute zu vergessen, daß der Code existiert, und potentiell für Performance Probleme verantwortlich sein kann.
Man kann Profiler und Query Analyzer verwenden, um herauszufinden, wie die Trigger in einer Datenbank arbeiten.

*****

Verwenden Sie keinen Trigger, um referenzielle Integrität sicherzustellen, wenn Sie die Option haben, auf die in SQL Server eingebauten Funktionen zur Sicherstellung referenzieller Integrität zurückzugreifen. Die Verwendung der hoch optimierten eingebauten referenziellen Integrität ist deutlich schneller als die Verwendung eines Triggers und interpretiertem Code, um die gleiche Aufgabe zu erfüllen.

*****

Wenn Sie die Wahl haben zwischen einem Trigger und einer CHECK Constraint, um Regeln oder Standards in der Datenbank sicherzustellen, sollte man sich generell für die CHECK Constraint entscheiden, da sie schneller sind als Trigger, wenn sie die gleiche Aufgabe erfüllen sollen

*****

Man sollte es vermeiden, einen Trigger zurückrollen zu müssen aufgrund des verursachten Overheads. Anstelle den Trigger ein Problem finden zu lassen und evtl. eine Transaktion zurückrollen zu müssen, sollte man den Fehler vorher versuchen abzufangen, falls das aufgrund des involvierten Codes möglich ist. Einen Fehler abzufangen (bevor der Trigger ausgelöst wird), verbraucht wesentlich weniger Server Resourcen als den Trigger zurückrollen zu müssen.

*****

Manchmal erscheint es aus Performancegrunden angebracht, denormalisierten Daten zu halten. Beispielsweise mag man aggregierte ( so z.B. kumulierte Daten) in einer Tabelle halten, da es einfach zu zeitaufwendig ist, sie on-the-fly innerhalb des SELECT Statements zu generieren. Ein Weg, diese denormalisierten Daten zu pflegen, ist die Verwendung von Triggern. Beispielsweise könnte ein Trigger immer dann ausgelöst werden, wenn ein neuer Verkauf zur Verkaufstabelle hinzugefügt wird und den Gesamtwert dieses Verkaufs zu einer Gesamtverkaufstabelle hinzufügen.

*****

Der Code, der in einem UPDATE Trigger enthalten ist, wird jedesmal ausgeführt, wenn seine zugrundeliegende Tabelle upgedatet wird. In den meisten UPDATE Triggern, betrifft der Code des Triggers nur einige wenige Spalten, nicht alle. Darum ist es nicht sinnvoll (und eine Verschwendung von SQL Server Resourcen) den gesamte Code des Triggers auszuführen, auch wenn die Spalten, an denen man ursprünglich interessiert war, überhaupt nicht aktualisiert worden sind. Mit anderen Worten, auch wenn eine Spalte aktualisiert wird, an der man nicht interessiert ist, wird der UPDATE Trigger ausgelöst und der Code ausgeführt.
Um nun die unnötige Ausführung von Code in einem UPDATE Trigger zu vermeiden, kann man eine der beiden folgenden Funktionen einsetzen: UPDATE() (verfügbar in SQL Server 2000) und COLUMNS_UPDATED() (verfügbar in SQL Server 7.0 und 2000).
Jede dieser beiden Funktionen kann verwenden werden, um zu testen, ob eine bestimmte Spalte sich verändert hat oder nicht. Daher kann man nun Code in seinem Trigger schreiben, der genau dies überprüft und falls sich diese Spalte nicht verändert hat, der Code halt nicht ausgeführt wird. Dies reduziert die Arbeit, die der Trigger ausführen muß und verbessert die allgemeine Performance der Datenbank.
Die UPDATE() Funktion wird verwendet, um die Veränderung einer einzelnen Spalte zu einer Zeit zu überprüfen. Die COLUMNS_UPDATED Funktion kann verwendet werden, um gleichzeitig mehrere Spalten zu überprüfen.

*****

Falls Sie kaskadierende referentielle Integrität (zum Beispiel kaskadierende DELETEs) in SQL Server 2000 Datenbanken, verwenden Sie kaskadierende referentielle Integritäts Constraints anstelle von Triggern, die die kaskadierenden DELETEs ausführen, da Constraints wesentlich effizienter sind und dadurch die Performance verbessern können. Falls man ältere (7.0 oder früher) Applikationen hat, die man auf SQL Server 2000 portiert hat und die Trigger benutzen, um kaskadierende DELETEs, sollte man in Erwägung ziehen, die Trigger, falls möglich zu entfernen und kaskadierende referentielle Integrität zu verwenden.

*****

Während INSTEAD OF trigger technisch identisch mit AFTER Triggern sind, liegt der Hauptgrund für die Verwendung von INSEAD OF Trigger darin, daß man mit ihnen bestimmte View Typen aktualisieren kann. Was bedeutet dies nun im Hinblick auf Performance? Unter der Annahme, daß die meisten, der von Ihnen geschriebenen Trigger, nur selten Transaktionen zurückrollen, kann man getrost weiterhin AFTER Trigger verwenden. Der Overhead eines INSTEAD OF Triggers ist größer als der eines AFTER Trigers. Ist es hingegen an der Regel, daß ROLLBACKs durchgeführt werden (mehr als in 50% aller Fälle), dann kann ein INSTEAD OF Trigger die bessere Alternative sein, da das ROLLBACK eines INSTEAD OF Triggers weniger Overhead verursacht als das eines AFTER Triggers. Also sollte man die meiste Zeit konventionelle AFTER Trigger verwenden, und sich die INSTEAD OF Trigger sparen, um damit Views upzudaten.

*****

SQL Server 2000 ermöglicht in gewissem Maße, Kontrolle über die Reihenfolge in der Trigger auszuüben. In gewissem Maße heißt, daß man angeben kann, welcher Trigger als Erster und welcher als Letzter ausgeführt wird. hat man jedoch mehr als zwei Trigger für eine Tabelle definiert, hat man keine Kontrolle über die Reihenfolge, in der die restlichen ausgeführt wird.
So, wie nun kann die Selektion der Reihenfolge, in der die Trigger ausgeführt werden, dabei helfen, die Performance einer Applikation zu verbessern? Um Trigger Performance zu optimieren, sollte man denjenigen Trigger, bei dem ein ROLLBACK am wahrscheinlichsten (aus welchem Grund auch immer), als ersten auszuführenden Trigger spezifizieren. Auf diese Weise ist nur dieser eine Trigger betroffen, wenn ein ROLLBACK durchgeführt werden muß.
Mal angenommen, man hat drei Trigger auf einer Tabelle definiert, aber anstelle dem am wahrscheinlichsten als ersten zu definieren, sei dieser als letzter definiert. Wird in diesem Szenario nun ein ROLLBACK ausgelöst, dann müssen alle drei Trigger. Wäre dieser Trigger aber als Erster definiert worden, hätte nur dieser Trigger zurückgerollt werden müssen. Verringert man die Anzahl der Trigger, die zurückgerollt werden müssen, reduziert man SQL Server's Overhead und verbessert die Performance.

Tags: Tags:
Dieser Eintrag wurde eingetragen von und ist abgelegt unter SQL Server. Tags: ,

Noch kein Feedback


Formular wird geladen...