Nach dem Wiederherstellen des Protokollversands auf dem sekundären Server ist die Ausführung der ersten gespeicherten Prozedur langsam


7

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:

  1. 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).
  2. 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_temporaryStatistiken, 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.


Bei der Abfrage von sys.dm_exec_query_stats scheint sich der älteste Plan-Cache nicht zu ändern, aber der neueste (nach dem Sortieren in desc nach Creation_time) wird aktualisiert und scheint während des Protokollversands kopiert zu werden, da sie danach dieselben Zeitstempel haben Die Wiederherstellung des Transaktionsprotokolls ist abgeschlossen. Es scheint jedoch keine Auswirkung auf die langsame erste Ausführung zu haben.
RIanGillis

Antworten:


8

Hier gibt es einige mögliche Dinge, hier ist eine nicht erschöpfende Liste:

  • Der Ausführungsplan-Cache wird durch die Protokollwiederherstellung gelöscht, sodass Pläne beim ersten Mal neu kompiliert werden müssen. Wenn Ihre Pläne lange Kompilierungszeiten haben, könnte dies den Unterschied erklären. Sie haben nicht genau erwähnt, wie lange die Verzögerung beim ersten Lauf im Vergleich zu den nachfolgenden Läufen dauert
    • Dies scheint am unwahrscheinlichsten zu sein - Sie können Ihre Planerstellungszeit in der tatsächlichen XML-Ausführung des Ausführungsplans sehen
  • Der Pufferpool wird auch während der Wiederherstellung gelöscht, sodass alle Daten bei der ersten Ausführung von der Festplatte gelesen werden müssen
    • Wenn dies der Fall ist, werden Sie wahrscheinlich PAGEIOLATCH*während des ersten Laufs hohe Wartezeiten sehen, wenn Sie die Wartestatistiken überprüfen

Einige Dinge, die Sie tun könnten, um dies zu mildern, sind

  • "Aufwärmen" des Puffercaches (durch Lesen aller Daten aus wichtigen Tabellen in den Speicher mit SELECT COUNT(*) FROM dbo.YourTable),
  • "Erwärmen" Sie den Proc-Cache, indem Sie alle kritischen gespeicherten Prozeduren als Schritt nach der Wiederherstellung ausführen

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:

SELECT * FROM sys.stats WHERE is_temporary = 1;

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 zur COUNT(*)Abfrage unterschiedliche Indizes verwendet werden . Sie haben hier einige Möglichkeiten:

  1. Gehen Sie jeden Ausführungsplan durch, notieren Sie sich die verwendeten Indizes und ziehen Sie diese Indizes als Schritt nach der Wiederherstellung in den Speicher - diesmal mit Indexhinweisen ( SELECT COUNT(*) FROM dbo.YourTable WITH (INDEX (IX_Index_Being_Used_By_Proc)))
  2. Führen Sie den Prozess des Skripts eines Prozesses durch, um jede Prozedur als Schritt nach der Wiederherstellung auszuführen (dies scheint etwas einfacher zu sein als Option 1).
  3. Optimieren Sie die Abfragen so, dass sie nicht so viele Lesevorgänge ausführen müssen (nicht sicher, wie machbar dies ist).
  4. Beschleunigen Sie das E / A-Subsystem - holen Sie sich schnellere Festplatten, lokale SSDs, mehr Kanäle zum SAN usw. (dies ist wahrscheinlich die schwierigste und teuerste Option
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.