Überlegungen bei der Verwendung von Triggern in einer replizierten (Ziel-) Datenbank

8

Unsere SQL Sever 2008-Anwendungsdatenbank wird von Server A auf Server B repliziert (Push-Replikation). Wir verwenden die Kopie, nennen wir sie database_b, auf Server B, um Berichte zu erstellen und andere Abfragen auszuführen, damit unsere Berichte die Anwendung nicht beeinträchtigen. Derzeit nutzen wir ineffiziente Ansichten, um Daten in mehreren Tabellen in database_b zu kombinieren, damit das Verfassen von Berichten für unsere Berichtsersteller (die über grundlegende SQL-Kenntnisse verfügen) vereinfacht wird.

99,9% der Datenbankaktivität sind INSERTS. Daher suchen wir nach einer Möglichkeit, die ineffizienten Ansichten durch Tabellen zu ersetzen, die wir optimieren können. Hier ist ein vereinfachtes Beispiel:

Es gibt eine appointmentTabelle und eine location(Nachschlagetabelle). Jedes Mal, wenn ein neuer Termin geplant ist, wird der appointmentTabelle eine Zeile hinzugefügt . Jedes Mal, wenn dieses EINFÜGEN passiert, möchte ich das appointment_idund den entsprechenden Standortnamen ( location_idaus beiden Tabellen verbinden) in eine Berichtstabelle einfügen .

Ich habe dies mit einem Trigger in der Termintabelle in database_b auf Server B erreicht.

Meine Frage ist - gibt es besondere Überlegungen, da database_b eine replizierte Kopie ist? Muss ich mir Sorgen machen, dass ein fehlerhafter Trigger den gesamten (Push-) Replikationsprozess durcheinander bringt? Fehlt mir noch etwas?

Leider ist es schwierig, dies in unserer Entwicklungsumgebung zu testen, so dass ich nicht die Möglichkeit habe, viel zu probieren.

JHFB
quelle
Sie sollten in der Lage sein, eine Publikation auf Ihrem Entwicklungsserver zu erstellen und dann eine Abonnementdatenbank mit einem anderen Namen zu erstellen, damit Sie auf demselben Server testen können. Ich habe das nicht persönlich gemacht, also YMMV.
DForck42
Erstellen Sie eine andere Instanz auf Ihrem Entwicklungsserver, auf die Sie für Entwicklungszwecke replizieren möchten. Dann können Sie testen!
Max Vernon
Vielen Dank für Ihr Feedback, Leute, aber ich kann das aus Gründen der Arbeitsregeln nicht. Es ist was es ist. Und selbst wenn ich es testen könnte, würde ich die Frage immer noch stellen. :)
JHFB
Dies hängt von der Art des Triggers ab. Wenn Sie einen Trigger nach dem Einfügen verwenden, ist dies in Ordnung. Ich würde Ihre Triggerlogik jedoch in einen Try / Catch-Block einfügen. Auf diese Weise wissen Sie, wenn bei Ihrer Einfügung ein Fehler auftritt, dass Ihre generierte Tabelle nicht synchron ist. Es ist auch wichtig zu beachten, dass bei der Replikation, wenn Sie neu initialisieren müssen, möglicherweise Ihr Trigger neu erstellt werden muss - dies hängt natürlich davon ab, wie Sie neu initialisieren. Eine andere Möglichkeit wäre, einen einfachen gespeicherten Prozess zu schreiben, der diese Daten in einem festgelegten Intervall - dh alle 10 Minuten - für Sie verschiebt / generiert.
Jeremy Lowell
.... Die letzte (gute) Option wäre, auch dafür SSIS zu verwenden - diese Optionen hängen jedoch alle davon ab, wie latent die Daten sein können - wenn die Berichterstellung mit Daten funktionieren kann, die 10 oder 15 Minuten alt sind, dann schreiben Ein Prozess außerhalb der Verwendung eines Trigger-basierten Ansatzes wäre die Option, auf die ich persönlich zuerst abzielen würde.
Jeremy Lowell

Antworten:

7

Dies klingt nach einer großartigen Situation, um indizierte Ansichten zu verwenden. Das klingt so ziemlich so: Eine Ansicht, die ihre Ergebnisse physisch in der Datenbank speichert und automatisch aktualisiert wird, wenn die Basistabellen aktualisiert werden.

Ein paar Vorsichtsmaßnahmen:

  • Wenn Sie viele davon in Ihrer Abonnementdatenbank haben, kann dies die Replikation verlangsamen (aber auch viele Auslöser).
  • Es gibt einige strenge SET-Optionen, die Sie ändern müssen, um sie zu erstellen, und Sie müssen WITH SCHEMABINDING verwenden, wenn Sie die Ansicht erstellen.
  • Es gibt zusätzliche strenge Anforderungen an das, was aus Ihrer Sicht sein kann. Beispielsweise können Sie keine äußeren Verknüpfungen, Aggregate oder Kreuz- / Außenanwendungen verwenden.
  • Wenn Sie die Standard Edition verwenden, müssen Sie die Ansicht mit dem WITH-Hinweis (NOEXPAND) nach Namen abfragen. SQL Server verwendet die Ansicht nicht automatisch, wenn Sie versuchen, die Basistabellen abzufragen.

Dieser Artikel enthält (viel) weitere Details sowie ein schönes Beispiel für die Verwendung der AdventureWorks-Datenbank:
http://msdn.microsoft.com/en-us/library/ms191432%28v=sql.100%29.aspx

Wenn es sich um eine relativ einfache Abfrage handelt, die aufgrund vieler Daten und (innerer) Verknüpfungen nur eine schlechte Leistung erbringt, kann dies eine einfache Möglichkeit sein, sie zu verbessern.

db2
quelle
Dies ist eine faszinierende Option, die ich heute untersuchen werde. Könnte dies die Replikation verlangsamen, da Daten in den Index geschrieben werden müssen, der in der Ansicht erstellt wird?
JHFB
Es stellt sich heraus, dass dies aufgrund von OUTER JOINS in der SELECT-Anweisung keine Option ist. :(
JHFB
Schade! Und um zu verdeutlichen, ja, der Aufwand für das Schreiben von Daten in die Ansicht würde sie verlangsamen. Aber Sie würden dies sowieso innerhalb von Triggern tun, sodass der Leistungsunterschied wahrscheinlich vergleichbar wäre.
db2
0

Ich schlage vor, dass Sie die folgenden Optionen prüfen, falls Sie dies noch nicht getan haben

  1. Weitergabe durch benutzerdefinierte gespeicherte Prozeduren. Sie könnten die Triggerlogik in diesem benutzerdefinierten Prozess haben. Der Nachteil ist jedoch, dass Ihr Abonnent und Ihr Publisher miteinander verbunden sind. http://msdn.microsoft.com/en-us/library/ms147880(v=sql.105).aspx

  2. Geben Sie an, dass die Änderung mit einer INSERT-, UPDATE- oder DELETE-Anweisung weitergegeben werden soll, und geben Sie den Auslöser an.

Diese Option kann die Replikation beschleunigen, wenn mehrere Zeilen mit einer einzigen Anweisung aktualisiert / eingefügt werden.

Afroz
quelle