Wir haben den Protokollversand an einen sekundären SQL Server im Standby / Schreibgeschützt eingerichtet, um die gesamte SSRS-Berichtsgenerierung auszulagern.
Dies funktioniert gut innerhalb der Einschränkungen, die auferlegt werden durch:
- Kickout des Benutzers während der Wiederherstellung des Transaktionsprotokolls (wir haben dies umgangen, indem wir mehrere Instanzen eingerichtet und die neuesten Transaktionsprotokolle mithilfe eines Round-Robin-Zeitplans wiederhergestellt haben).
- Die Daten sind höchstens um den Zeitrahmen veraltet, der durch den geplanten Sicherungs- / Wiederherstellungsjob für das Transaktionsprotokoll angegeben wird.
Leider dauert es beim ersten Ausführen einer gespeicherten Prozedur nach der Wiederherstellung des Transaktionsprotokolls viel länger als normal. Alle nachfolgenden Ausführungen derselben gespeicherten Prozedur werden innerhalb der erwarteten Zeit abgeschlossen. Wenn wir dann eine andere gespeicherte Prozedur ausführen, ist diese beim ersten Mal langsam und alle nachfolgenden Ausführungen werden in der erwarteten Zeit abgeschlossen.
Als Referenz beträgt der Ausführungsunterschied normalerweise ~ 00: 02 im Vergleich zu ~ 01: 00 beim ersten Durchlauf.
Ich gehe davon aus, dass dies entweder mit der Serverausführungsstatistik oder dem gespeicherten Prozedurparameter Sniffing / gespeicherter Ausführungsplan zu tun hat.
Gibt es eine Möglichkeit, dieses Problem zu umgehen? Oder ist dies mit der Wiederherstellung des Transaktionsprotokolls verbunden?
Wenn es nur die allererste Ausführung einer gespeicherten Prozedur wäre, könnten wir dies leicht umgehen, indem wir eine gespeicherte Prozedur bei der Wiederherstellung ausführen. Dies scheint sich jedoch auf die erste Ausführung aller gespeicherten Prozeduren auszuwirken.
Ich habe versucht, count( * )
die gespeicherte Prozedur, die ich zum Testen von Berührungen verwende , auf den 11 Tabellen auszuführen. Der erste Lauf dauerte 00:32 und die nachfolgende Zählung (*) dauerte 00:00. Leider hatte dies keine Auswirkungen auf den ersten Lauf der gespeicherten Prozedur.
Ich sehe weder auf meinem primären noch auf meinem sekundären Server Ergebnisse für is_temporary
Statistiken, weder vor noch nach der Ausführung einer gespeicherten Prozedur.
Ich bin derzeit im SQL Server 2012-
Abfrageexektionsplan:
Der Abfrageausführungsplan sieht auf den ersten Blick erheblich anders aus. Beim Speichern des Ausführungsplans und Öffnen der generierten SQL-Plan-Datei sind sie jedoch exakt gleich. Der Unterschied scheint auf die verschiedenen Versionen von SSMS zurückzuführen zu sein, die ich verwende, 2014 auf dem Primärserver und 2018 auf dem Sekundärserver. Wenn der Ausführungsplan auf der Sekundärseite angezeigt wird, werden unter den% und Zeitkosten jedes Knotens ### von ### (##%) angezeigt - weder diese Zahlen noch der tatsächliche Ausführungsplan ändern sich bei weiteren Ausführungen.
Ich habe auch Client-Statistiken eingefügt, die fast genau gleich sind. Der einzige Unterschied besteht darin, dass der Primärserver mit einer Wartezeit von 1,4 Sekunden bei Serverantworten ausgeführt wird und der Sekundärserver 81,3 Sekunden benötigt.
Ich sehe eine große Anzahl von PAGEIOLATCH_SH-Sperren von der ersten Ausführung an, wie Sie vorausgesagt haben:
diff after first exec vs diff after second exec
waiting_tasks_count 10903 918
wait_time_ms 411129 12768
Eines der merkwürdigen Dinge in dieser Situation ist, dass unser Produktions-SSRS-Server mit Ausnahme des Round-Robin-Teils mehrerer Instanzen des Setups bereits aus einer Standby- / Nur-Lese-Datenbank gelesen wird, die von regelmäßigen Transaktionsprotokollen gespeist wird und keine Erfahrung aufweist Diese verlangsamen sich bei der ersten Ausführung einer gespeicherten Prozedur. Unsere Benutzer werden jedoch jedes Mal gestartet, wenn das Transaktionsprotokoll wiederhergestellt wird. Dies ist das Problem, das mit dem obigen Setup behoben werden soll.
Antworten:
Hier gibt es einige mögliche Dinge, hier ist eine nicht erschöpfende Liste:
PAGEIOLATCH*
während des ersten Laufs hohe Wartezeiten sehen, wenn Sie die Wartestatistiken überprüfenEinige Dinge, die Sie tun könnten, um dies zu mildern, sind
SELECT COUNT(*) FROM dbo.YourTable
),Wenn Sie uns ein "schnelles" und "langsames" Beispiel für einen Ausführungsplan geben, können Sie genau feststellen, was gerade passiert.
Wenn Sie mit SQL Server 2012 oder neuer arbeiten, kann es sein, dass Aktualisierungen der Synchronisierungsstatistiken die Verzögerung verursachen. Diese "lesbaren sekundären Statistiken" werden in TempDB erstellt, da der sekundäre Protokollversand schreibgeschützt ist. Sie können hier mehr darüber lesen (der Artikel handelt von AGs, aber das Gleiche gilt für dieses Szenario):
AlwaysOn: Bereitstellung der neuesten Statistiken für lesbare sekundäre, schreibgeschützte Datenbanken und Datenbank-Snapshots
Wenn dies das Problem ist, das Ihre Verlangsamung verursacht, besteht eine Lösung darin, diese Statistiken zu finden und sie dann in der Produktionsdatenbank zu erstellen, damit sie nach der Wiederherstellung auf dem neuesten Stand und verfügbar sind. Mit dieser Abfrage können Sie nach temporären Statistiken suchen:
Basierend auf den von Ihnen angegebenen Wartestatistiken und der Tatsache, dass die Pläne identisch sind, ist dies ziemlich schlüssig, da der Pufferpool durch die Protokollwiederherstellung gelöscht wird.
Bei einem normalen Lauf erhalten Sie 12.768 ms (fast 13 Sekunden) E / A-Wartezeiten.
Beim ersten Durchlauf erhalten Sie 411.129 ms (fast 7 Minuten ) E / A- Wartezeiten.
Der von
SELECT COUNT(*)
Ihnen versuchte Ansatz hat möglicherweise nicht geholfen, da von der tatsächlichen Prozedur im Vergleich zurCOUNT(*)
Abfrage unterschiedliche Indizes verwendet werden . Sie haben hier einige Möglichkeiten:SELECT COUNT(*) FROM dbo.YourTable WITH (INDEX (IX_Index_Being_Used_By_Proc))
)quelle