Ratgeber · SQL Server Performance

SQL Server Performance verbessern und Ursachen finden

Die Auftragsliste öffnet sich morgens sofort. Eine Stunde später wartet das Team mehrere Sekunden auf dieselbe Ansicht. Am nächsten Tag ist wieder alles schnell. Wo beginnt die Suche?

Stand 21.10.2026 · ca. 9 Minuten

Diagnosewege 6SQL-Abfragen 4Geprüft SQL Server 2017–2025
AntwortzeitSQL 1SQL 2ÜbertragungAnwendung

Wer die SQL Server Performance verbessern möchte, braucht zuerst einen eingegrenzten Befund: Welche Aufgabe ist zu langsam, wann tritt das auf und was unterscheidet den schnellen vom langsamen Zustand? Ausführungspläne, Parameter und Wartezeiten helfen, diese Fragen zu beantworten.

Dieser Ratgeber führt Sie durch die ersten Prüfschritte. Sie wählen den Diagnoseweg, der zu Ihrer Beobachtung passt, vergleichen Messwerte, ordnen sie ein und begründen den nächsten Test. Die ausführlichen Wege enthalten lesende SQL-Abfragen zum Kopieren, geprüft auf SQL Server 2017 bis 2025. Sie benötigen dafür kein PSG-Werkzeug.

Was genau ist bei Ihrem SQL Server langsam?

Beschreiben Sie zunächst eine konkrete Aufgabe: etwa eine Auftragsliste, eine Suche oder einen nächtlichen Bericht. „Der Server ist langsam“ ist verständlich, umfasst aber viele mögliche Ursachen.

Diese drei Fragen helfen beim Eingrenzen:

FrageWas Sie festhalten sollten
Ist eine einzelne Aufgabe betroffen oder sind es viele?Anwendung, Funktion und betroffene Datenbank
Tritt das Problem ständig oder nur zeitweise auf?Beginn, Ende und Häufigkeit; möglichst ein schneller und ein langsamer Zeitraum
Was hat sich seit dem schnellen Zustand verändert?Zum Beispiel Parameter, Datenmenge, Softwarestand, Wartung oder gleichzeitig laufende Arbeit

Halten Sie auch fest, wo Sie die Zeit messen. Die Wartezeit eines Menschen vor einer Anwendung umfasst mehr als die Ausführung eines einzelnen SQL-Statements. Dazu können mehrere Datenbankaufrufe, die Übertragung der Ergebnisse und die Verarbeitung in der Anwendung gehören. Wenn die Abfrage in SQL Server schnell beendet ist, die Ansicht aber weiter lädt, gehört deshalb auch der Anwendungsweg zur Untersuchung.

Wählen Sie den passenden Diagnoseweg

Suchen Sie die Zeile, die Ihre Beobachtung am besten beschreibt. Die Wege überschneiden sich: Ein Planwechsel kann zum Beispiel zusätzliche Sperren verursachen. Wo das passiert, verweisen die Wege aufeinander.

Die Wege 02 bis 04 haben eigene, ausführliche Seiten mit SQL-Abfragen. Die Wege 01, 05 und 06 finden Sie direkt hier in Kurzform, mit Verweisen auf passende Beiträge.

Steht ein Neustart an? Sichern Sie vorher das Lagebild. Warum hilft ein Neustart, und warum nur kurz? zeigt, was ein Neustart löscht und wie Sie die Belege in fünf Minuten sichern.

Eine Abfrage ist dauerhaft langsam

Woran verliert diese Abfrage ihre Zeit? Diese fünf Schritte grenzen es ein:

  1. Die richtige Abfrage finden. Ordnen Sie den langsamen Anwendungsschritt dem tatsächlich ausgeführten Statement zu. Ruft eine Procedure weitere Statements, Trigger oder Funktionen auf, gehört deren Zeit zum äußeren Aufruf dazu.
  2. Blocking ausschließen. Läuft die Abfrage lange, weil sie auf eine Sperre wartet, hilft kein Tuning. Prüfen Sie das während eines langsamen Laufs mit der Abfrage zur Blocking-Kette.
  3. Arbeit messen. Auf einem Testsystem mit vergleichbaren Daten zeigen SET STATISTICS IO ON und SET STATISTICS TIME ON die gelesenen Seiten je Tabelle und die CPU-Zeit. Achtung: Dafür wird die Abfrage erneut ausgeführt, mit allem Aufwand und bei ändernden Statements auch mit ihren Änderungen.
  4. Den Plan lesen. Schalten Sie in SSMS Tatsächlichen Ausführungsplan einschließen ein (Strg+M). Achten Sie auf große Abweichungen zwischen geschätzten und tatsächlichen Zeilen, auf sehr viele Lookups und auf Warnsymbole, etwa wenn eine Sortierung nicht in den zugeteilten Speicher passt und auf TempDB ausweicht. Nicht jede Warnung ist automatisch die Ursache.
  5. Einen begrenzten Test wählen: einen anderen Zugriffsweg oder Index, eine geänderte Abfrageform oder eine bessere Schätzung. Danach mit denselben Daten nachmessen.

Vertiefung: Parameter Sniffing in SQL Server verstehen erklärt Schätzung, Kompilierung und Planwiederverwendung. Hat Ihre Abfrage viele optionale Suchbedingungen, zeigt T-Lift einen möglichen Weg.

Der Performance-Einbruch ist vorbei und die Belege fehlen

Was lässt sich jetzt noch herausfinden, und was sollten Sie beim nächsten Mal erfassen? Ganz ohne Spuren ist ein vergangener Einbruch selten.

Was oft noch vorhanden ist:

  • Query Store, wenn er für die Datenbank eingeschaltet war: Laufzeiten und Pläne je Zeitfenster. Die Abfrage „Teuerste Abfragen im Zeitfenster“ zeigt sie für den fraglichen Zeitraum, einschließlich abgebrochener Ausführungen.
  • Die Sitzung system_health, die standardmäßig läuft: Sie zeichnet unter anderem Deadlocks auf sowie Sitzungen, die länger als 30 Sekunden auf eine Sperre gewartet haben. Wie weit sie zurückreicht, hängt davon ab, wie viel seitdem aufgezeichnet wurde. Microsoft beschreibt, was system_health erfasst.
  • Das Errorlog von SQL Server, etwa mit Meldungen über sehr langsame I/O-Anforderungen (Meldung 833).
  • Monitoring und Anwendungslogs, sofern vorhanden.

Was nicht mehr da ist: die damalige Blocking-Kette, die damals laufenden Requests und ihre Wartezeiten. Auch der Plan, der heute im Cache liegt, ist nicht unbedingt der Plan der langsamen Ausführung. sys.dm_os_wait_stats zählt seit dem Start der Instanz und kennt kein Zeitfenster.

Wurde der Server inzwischen neu gestartet, fehlt noch mehr: Plan Cache, Ausführungsstatistiken und Wartezeiten beginnen wieder bei null. Wenn ein Neustart ansteht, sichern Sie vorher das Lagebild; wie das in fünf Minuten geht und warum ein Neustart oft nur kurz hilft, zeigt Warum hilft ein Neustart, und warum nur kurz?

Für das nächste Mal:

  1. Halten Sie Zeitpunkt, betroffene Aufgabe und Zeitbasis fest.
  2. Schalten Sie Query Store für die betroffene Datenbank ein, falls er fehlt. Das ist eine Änderung an der Datenbank; stimmen Sie sie mit dem Betrieb ab.
  3. Legen Sie die Abfrage zur Blocking-Kette und die Abfrage zu Wartezeiten im Fenster bereit, um sie beim nächsten Auftreten sofort auszuführen.
  4. Gezielte zusätzliche Aufzeichnungen wie Blocked Process Reports sind Konfigurationsänderungen. Richten Sie sie nur begründet, begrenzt und abgestimmt ein; Hinweise dazu im Diagnoseweg Blocking.

Halten Sie die Lücke ehrlich fest: „Der Zeitraum ist nicht aufgezeichnet“ ist ein gültiger Befund und begründet die bessere Vorbereitung.

Wartung, Jobs oder Schreiblast sind zu langsam

Arbeitet der Job, oder wartet er? Und hilft die Wartung der Arbeitslast danach? Vier Schritte bringen Klarheit:

  1. Arbeiten oder warten? Führen Sie während des Joblaufs die Abfrage zur Blocking-Kette und die Abfrage zu Wartezeiten im Fenster aus. Viele kleine Commits zeigen sich zum Beispiel als WRITELOG: Jeder Commit wartet, bis das Transaktionsprotokoll geschrieben ist.
  2. Indexwartung und Statistikpflege trennen. Das sind zwei verschiedene Aufgaben mit verschiedenen Zielen.
  3. Fragmentierung ist allein kein Entscheidungsgrund. Wichtiger sind die tatsächliche Lese- und Schreiblast, die Seitendichte und der Zugriffsweg.
  4. Wirkung an der Folgelast messen. Ein grüner Wartungsjob oder ein niedriger Fragmentierungswert sagt noch nicht, ob die nächste Arbeitslast schneller ist. Vergleichen Sie Kosten und Nutzen.

Vertiefung: unsere Reihe Indexwartung verstehen, REORGANIZE und REBUILD in der Gegenprobe und Wachstum ohne Wartung. Backup-, ETL- und andere Agent-Jobs behandelt dieser Ratgeber noch nicht.

Antwortzeit, CPU-Arbeit und Warten auseinanderhalten

Fast jede Diagnose scheitert früher oder später an derselben Verwechslung: Antwortzeit, CPU-Zeit und Wartezeit werden zusammengezählt, als wären sie Teile derselben Strecke. Das folgende Schema zeigt, wie sie zusammenhängen.

Antwortzeit in der AnwendungSQL-Aufruf 1SQL-Aufruf 2Ergebnisse zum Client übertragenVerarbeitung in der AnwendungRechnen in SQL Server (CPU-Zeit)Warten in SQL ServerÜbertragen der ErgebnisseArbeit außerhalb von SQL ServerSchema, keine Messung
AntwortzeitSQL 1SQL 2ÜbertragungAnwendungRechnen in SQL Server (CPU-Zeit)Warten in SQL Server (Sperre, Platte, freier Kern …)Übertragen und Abholen der ErgebnisseArbeit außerhalb von SQL ServerSchema, keine Messung
Die Antwortzeit umfasst mehr als die Arbeit in SQL Server. Schema, keine Messung.

Vier Regeln helfen beim Lesen jeder Messung:

  1. Die Antwortzeit hängt an der Messstelle. Eine Stoppuhr in der Anwendung misst mehr als die Dauer eines Statements in SQL Server.
  2. CPU-Zeit kann größer sein als die Dauer. Bei paralleler Ausführung rechnen mehrere Worker gleichzeitig; ihre CPU-Zeit wird addiert. Unser CPU-Lab zeigt eine Abfrage, die parallel in 89 statt 289 Millisekunden fertig war und dabei mehr CPU verbrauchte.
  3. Wartezeiten vieler Sitzungen überlappen sich. Acht Sitzungen, die gleichzeitig drei Sekunden warten, ergeben 24 Sekunden Wartezeit in drei Sekunden Echtzeit. Das zeigt unser Waits-Lab.
  4. Verschachtelte Aufrufe zählen doppelt. Die Dauer einer Procedure enthält die Dauer der Statements, die sie aufruft. Der Beitrag Query Store bei Triggern, Procedures und Funktionen zeigt das an eigenen Beispielen.

Addieren Sie deshalb CPU-Zeit und Wartezeiten nie zu einer vermeintlichen Antwortzeit. Vergleichen Sie jede Größe mit sich selbst: schneller gegen langsamer Zeitraum, vorher gegen nachher.

Hat die Änderung wirklich geholfen?

Eine Maßnahme ist erst dann ein Erfolg, wenn der Vergleich trägt. Prüfen Sie nach jeder Änderung:

  • Dieselbe fachliche Aufgabe mit vergleichbaren Daten, Parametern und Ergebnismengen.
  • Vergleichbare Last: gleiche Tageszeit, ähnlicher Arbeitsmix, keine zusätzlich laufenden Jobs.
  • Gleiches Ergebnis: Liefert die Abfrage dieselben Daten wie vorher?
  • Zeit und Arbeit: Dauer, CPU-Zeit und gelesene Seiten getrennt betrachten.
  • Nebenwirkungen: Werden andere Vorgänge langsamer? Steigen Speicherbedarf oder Schreibaufwand?
  • Wiederholung: Ein einzelner schneller Aufruf beweist bei einem sporadischen Problem wenig. Beobachten Sie mehrere vergleichbare Zeiträume.

Ein Beispiel für diesen Weg vom Befund zur Nachmessung ist unser Praxisfall mit Statistik und erzwungenem Plan.

Beispiele aus unseren Untersuchungen

Diese Beiträge vertiefen einzelne Fragen aus den Diagnosewegen:

BeitragWelche Frage er beantwortet
Parameter Sniffing in SQL Server verstehenWarum dieselbe Abfrage unterschiedliche Pläne bekommt
sp_BlitzPlanCompare: Test schnell, Produktion langsamWie Sie Pläne und Parameter zweier Server vergleichen und einen Unterschied als Ursache belegen
Query Store bei Triggern, Procedures und FunktionenWo die Zeit bei verschachtelten Aufrufen tatsächlich steckt
Lock Escalation durch SELECT in SQL ServerWie ein lesender Zugriff eine ganze Tabelle sperren kann
Indexwartung verstehen und die beiden FolgebeiträgeWann Indexwartung der Arbeitslast hilft und was sie kostet
Praxisfall: Statistik und erzwungener PlanWie ein festgehaltener Plan eine Verbesserung verhinderte
T-LiftWie sich Abfragen mit vielen optionalen Suchbedingungen entschärfen lassen

So halten Sie Ihren Befund fest

Ein kurzer, belegter Befund hilft Ihnen selbst, Ihrem Team und jedem, den Sie später hinzuziehen. Kopieren Sie diese Vorlage und füllen Sie sie aus:

Befundblatt zum Kopieren
Betroffene Aufgabe:   Welcher Vorgang oder Jobschritt ist zu langsam?
Zeitraum:             Von/bis mit Zeitzone; aktuell, vergangen oder nachgestellt?
Vergleich:            Schneller Zustand oder Ziel; Parameter und Ergebnismenge
Belege:               Messwerte mit Quelle (Anwendung, Query Store, DMV, Plan) und Grenzen
Arbeitshypothese:     Welche Erklärung wird durch welchen Beleg gestützt?
Nächster Schritt:     Welche Beobachtung oder Gegenprobe unterscheidet die Erklärungen?
Wirkung:              Nach einer Änderung: gleiches Ergebnis? Zeit, Arbeit, Nebenwirkungen?

Ausgefüllt für unser Blocking-Lab sieht das so aus:

Befundblatt, ausgefüllt für das Blocking-Lab
Betroffene Aufgabe:   Ändern von Zeile 2 (Verbindung C) hängt
Zeitraum:             Nachgestellt im Lab, SQL Server 2022
Vergleich:            Ohne die offene Transaktion in A läuft die Änderung sofort durch
Belege:               Abfrage zur Blocking-Kette: Pfad A <- B <- C; A sleeping mit
                      1 offenen Transaktion; B und C warten mit LCK_M_X
Arbeitshypothese:     A hält nach seinem UPDATE eine Transaktion offen und sperrt Zeile 1
Nächster Schritt:     Mit dem Entwicklungsteam klären, warum A nicht abschließt
Wirkung:              Nach Rollback in A liefen B und C weiter; Wiederholung beobachten

Am Ende muss nicht jede Ursache bewiesen sein. Ein klarer Unterschied zwischen zwei Zuständen und ein begründeter nächster Test bringen die Untersuchung bereits weiter.