🔧 PERFORMANCE TUNING FÜR DBAS

SQL Server Performance Tuning

Das vollständige Handbuch für DBAs: Tools, Methoden und Best Practices zur Identifikation und Behebung von Performance-Engpässen – von DMVs über Query Plans bis zu Blocking und I/O.

🎯 Zielgruppe: SQL-Administratoren, Datenbankentwickler 📅 SQL Server 2016 – 2025

🔩 Das Toolkit – Werkzeuge für den DBA

Von eingebauten DMVs bis zu spezialisierten Community-Tools

📊 DMVs (Dynamic Management Views)

Das Herzstück der Performance-Analyse. DMVs liefern Echtzeit-Statistiken über laufende Abfragen, Indexnutzung, Waits, Locking und mehr. Sie sind die erste Anlaufstelle für jeden DBA.

sys.dm_exec_query_stats sys.dm_os_wait_stats sys.dm_db_index_usage_stats

🐚 Query Store

Der Query Store zeichnet historische Abfrageleistung auf und ermöglicht es, Planregressionen zu erkennen und Pläne zu erzwingen. Ab SQL Server 2025 auch auf lesbaren Secondaries verfügbar.

🔬 Extended Events

Moderne, leichtgewichtige Alternative zum Profiler. Erzeugt minimalen Overhead (ca. 80% weniger als Profiler) und ist hochgradig konfigurierbar – der empfohlene Standard für SQL Server 2016+.

📈 Performance Monitor (PerfMon)

Windows-Bordmittel zur Überwachung von CPU, Memory, Disk I/O und SQL Server-spezifischer Objekte wie Locks, Buffer Manager und Access Methods.

📋 Standard Reports

SSMS-Berichte zu Memory, Top Queries, Blocking – ohne Setup, direkt verfügbar.

📐 Query Plans

Grafische, XML- und Textpläne – die Visitenkarte jeder Abfrage.

⚙️ Database Tuning Advisor (DTA)

Analysiert Workloads und empfiehlt Indizes, Partitionierungen und materialisierte Sichten.

🛠️ msSQLTools (dtcSoftware)

Das PowerShell-Modul von dtcSoftware (Webseite: dtc-sql.de) bietet über 74 Funktionen für Performance-Analyse, Diagnose und Automatisierung – spezialisierte Cmdlets für AlwaysOn, Waiter-Analyse und Health-Checks.

# msSQLTools Beispiel: Health-Check und Waiter-Analyse
Get-mssPerformanceWaiter -SqlInstance "PRODSQL01" -WaitMinutes 15
Get-mssMissingIndexes -SqlInstance "PRODSQL01" -Database "AdventureWorks"
Invoke-mssHealthCheck -SqlInstance "PRODSQL01" -OutputHtml

🧩 Weitere Community-Tools

dbatools: PowerShell-Modul für Migration, Index-Wartung, Backup-Restore.
sp_WhoIsActive: Adam Machanics berühmte Prozedur für aktuelle Session-Analyse.
Plan Explorer (SolarWinds): Kostenloses Tool zur detaillierten Analyse von Ausführungsplänen.

📊 DMVs – Die wichtigsten Queries für den DBA-Alltag

Praktische Abfragen zur sofortigen Performance-Analyse
-- 1. Aktuelle teure Abfragen (nach CPU)
SELECT TOP 10
  t.text AS Query,
  qs.total_worker_time / qs.execution_count AS AvgCPU_ms,
  qs.total_logical_reads / qs.execution_count AS AvgReads,
  qs.execution_count
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t
ORDER BY AvgCPU_ms DESC;

-- 2. I/O-Waits (PAGEIOLATCH = I/O Engpass)
SELECT wait_type, waiting_tasks_count, wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type LIKE 'PAGEIOLATCH%' OR wait_type LIKE 'WRITELOG%'
ORDER BY wait_time_ms DESC;

-- 3. Unbenutzte Indizes (0 Reads, viele Updates)
SELECT OBJECT_NAME(i.object_id) AS TableName, i.name AS IndexName,
    s.user_seeks, s.user_scans, s.user_lookups, s.user_updates
FROM sys.indexes i
JOIN sys.dm_db_index_usage_stats s ON i.object_id = s.object_id AND i.index_id = s.index_id
WHERE s.user_seeks = 0 AND s.user_scans = 0 AND s.user_lookups = 0
  AND s.user_updates > 0
ORDER BY s.user_updates DESC;

-- 4. Fehlende Indizes (Missing index requests)
SELECT
  mid.statement AS TableName,
  migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) AS Impact,
  'CREATE INDEX idx_missing ON ' + mid.statement + ' (' + ISNULL(mid.equality_columns,'') +
  ISNULL(mid.inequality_columns,'') + ') INCLUDE (' + ISNULL(mid.included_columns,'') + ')'
FROM sys.dm_db_missing_index_groups mig
JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle
JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle
WHERE mid.database_id = DB_ID()
ORDER BY Impact DESC;
⚠️ Wichtige Einschränkung: DMVs setzen sich nach jedem SQL Server-Neustart zurück. Für aussagekräftige Statistiken sollten Sie mindestens 14 Tage Betriebszeit haben – sonst sind Index-Nutzungsstatistiken verfälscht.

🎣 SQL Server Profiler vs. Extended Events

Warum Extended Events heute die bessere Wahl sind

📼 SQL Server Profiler (deprecated)

  • Grafische Benutzeroberfläche, einfach zu starten
  • Nachteil: Hoher Performance-Overhead (5-15% CPU auf produktiven Systemen)
  • Wurde mit SQL Server 2012 als veraltet markiert
  • Nur für einmalige Diagnose geeignet, nicht für Dauerbetrieb

🚀 Extended Events (empfohlen)

  • Asynchrone, nicht-blockierende Architektur
  • Ca. 80% weniger Performance-Overhead als Profiler
  • Hochgradig konfigurierbar (Filter, Aktionen, Ziele)
  • Kann im Produktivbetrieb ohne Auswirkungen laufen
  • Ersetzt vollständig SQL Trace und Profiler
-- Extended Events Session für Deadlock-Aufzeichnung
CREATE EVENT SESSION [TrackDeadlocks] ON SERVER 
ADD EVENT sqlserver.xml_deadlock_report
ADD TARGET package0.event_file(SET filename = N'C:\XEvents\Deadlocks.xel')
WITH (MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY = 30 SECONDS, STARTUP_STATE = ON);
GO
ALTER EVENT SESSION [TrackDeadlocks] ON SERVER STATE = START;

📈 Performance Monitor (PerfMon) – Die Systemperspektive

Wichtige Counters für SQL Server
ObjektCounterAussage
Processor% Processor TimeCPU-Auslastung (Gesamt) – Werte über 80% über längere Zeit kritisch
MemoryPage Life ExpectancySeitenlebensdauer im Buffer Pool – unter 300 Sekunden = RAM-Knappheit
PhysicalDiskAvg. Disk sec/Read, Avg. Disk sec/WriteLatenz – über 10-15 ms = I/O-Engpass[reference:0]
SQL Server:Buffer ManagerBuffer cache hit ratioDatenbankseiten im Cache – über 90% ist gut
SQL Server:LocksNumber of Deadlocks/secDeadlocks pro Sekunde – konstant >0 = Problem

📋 Standard Reports & Query Plans

Die schnellsten Einstiege ins Performance Tuning

📑 Standard Reports (SSMS)

Rechtsklick auf Server/Datenbank → Reports → Standard Reports. Mehr als 20 Berichte für:

  • Memory Consumption
  • Top Transactions by Age
  • Performance – Batch Execution Statistics
  • Object Execution Statistics
  • Blocking Transactions

🔍 Query Plans – Der Schlüssel zur Optimierung

Ausführungspläne zeigen genau, wie SQL Server eine Abfrage verarbeitet:

  • Grafisch: In SSMS, zeigt Operatoren mit Kostenprozenten
  • XML: Für detaillierte Analyse mit Drittanbieter-Tools
  • Estimated vs. Actual: Estimated = Optimierer-Schätzung, Actual = echte Laufzeit

Rote Pfeile auf Operatoren (Seek vs. Scan) sind erste Warnsignale.

⚙️ Database Engine Tuning Advisor (DTA)

Automatisierte Index- und Partitionierungsempfehlungen

Der DTA analysiert eine Workload (z. B. eine Profiler-Trace-Datei, eine T-SQL-Skriptdatei oder den Query Store) und gibt Empfehlungen für Indizes, Indexed Views und Partitionierungen. Besonders wertvoll für:

  • Identifikation fehlender Indizes
  • Erkennung überflüssiger Indizes
  • Optimierung der Index-Partitionierung
-- Workload aus Query Store für DTA exportieren
SELECT q.query_id, qt.query_sql_text
FROM sys.query_store_query q
JOIN sys.query_store_query_text qt ON q.query_text_id = qt.query_text_id
WHERE q.last_execution_time > DATEADD(day, -7, GETUTCDATE());
⚠️ DTA-Empfehlungen immer mit Vorsicht prüfen: Das Tool kann aggressive Index-Vorschläge machen. Testen Sie Änderungen immer zuerst in einer Nicht-Produktionsumgebung.

🔒 Blocking & Deadlocks – Sperrprobleme verstehen und lösen

Die häufigste Ursache für schlechte Performance in OLTP-Systemen

🛑 Blocking – Der leise Performance-Killer

Blockierung entsteht, wenn eine Transaktion Sperren auf Ressourcen hält, während andere darauf warten. Blockings-Probleme erkennen Sie mit:

  • sys.dm_exec_requests (Spalte blocking_session_id)
  • Standard Report "Blocking Transactions"
  • Extended Events mit blocked_process_report

💀 Deadlocks – Der tödliche Zirkel

Zwei Transaktionen warten gegenseitig auf die Ressourcen der anderen. SQL Server wählt einen "Victim" und killed eine der Transaktionen. Behebung durch:

  • Indizes optimieren (weniger Scan-Operatoren)
  • Zugriffsreihenfolgen standardisieren
  • Transaktionen kürzer halten
  • READ COMMITTED SNAPSHOT aktivieren
-- Aktuelle Blockings-Situation analysieren
SELECT 
  blocked.session_id AS Blocked_Session,
  blocked.blocking_session_id AS Blocker_Session,
  blocked.wait_type, blocked.wait_time,
  t.text AS Blocked_Query
FROM sys.dm_exec_requests blocked
CROSS APPLY sys.dm_exec_sql_text(blocked.sql_handle) t
WHERE blocked.blocking_session_id > 0;

🗂️ Index Scans, Lookups & Unused Indexes

Die drei großen Index-Fallstricke im Überblick

📊 Index Scan vs. Index Seek

Seek: optimal – direkter Zugriff auf die gesuchten Zeilen über B‑Tree.
Scan: suboptimal – der Index wird vollständig durchlaufen (wie eine Tabelle).

Ein Index Scan tritt typischerweise auf, wenn die WHERE-Klausel nicht mit der Index-Struktur kompatibel ist oder der Optimierer eine hohe Selektivität annimmt.

📎 Lookups – Die versteckte Kostenfalle

Ein RID oder Key Lookup entsteht, wenn ein Nonclustered Index verwendet wird, aber zusätzliche Spalten aus der Tabelle benötigt werden. Diese Lookups sind teure Einzelzugriffe. Abhilfe: Include-Spalten im Index oder den Index als covering Index definieren.

🗑️ Unused Indexes

Nicht genutzte Indizes schaden: Sie verbrauchen Speicher, verlangsamen INSERT/UPDATE/DELETE und verlängern Backup-Zeiten. Identifizieren Sie sie mit sys.dm_db_index_usage_stats – wenn user_seeks/user_scans/user_lookups = 0 und user_updates > 0, ist der Index ein Kandidat für die Löschung.

-- Kandidaten für ungenutzte Indizes (nach 14+ Tagen Uptime)
SELECT OBJECT_NAME(i.object_id) AS TableName, i.name AS IndexName,
    s.user_seeks, s.user_scans, s.user_lookups, s.user_updates,
    'DROP INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' + QUOTENAME(OBJECT_NAME(i.object_id)) AS DropCommand
FROM sys.indexes i
LEFT JOIN sys.dm_db_index_usage_stats s ON i.object_id = s.object_id AND i.index_id = s.index_id AND s.database_id = DB_ID()
WHERE i.type_desc IN ('NONCLUSTERED', 'CLUSTERED')
  AND (s.user_seeks + s.user_scans + s.user_lookups = 0 OR s.user_seeks IS NULL)
  AND s.user_updates > 0
ORDER BY s.user_updates DESC;

💾 I/O-Bottlenecks – Das unterschätzte Problem

Wie Sie I/O-Engpässe erkennen und beheben

I/O-Probleme sind für bis zu 50% aller Performance-Probleme verantwortlich. Erkennungskriterien:

  • Wait-Statistiken: PAGEIOLATCH_* über 200 ms durchschnittliche Wartezeit
  • PerfMon-Latenzen: Avg. Disk sec/Read > 10-15 ms konsistent[reference:1]
  • Page Life Expectancy (PLE) unter 300 Sekunden (RAM-Engpass führt zu vermehrten I/Os)
-- I/O-Wait-Typen analysieren
SELECT wait_type, waiting_tasks_count, wait_time_ms, max_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type IN ('PAGEIOLATCH_SH', 'PAGEIOLATCH_EX', 'WRITELOG', 'IO_COMPLETION')
ORDER BY wait_time_ms DESC;
💡 Lösungsansätze: Fehlende Indizes ergänzen, TempDB Splitting, Datenbanken auf schnellere SSDs/NVMe verschieben, Buffer-Pool vergrößern, In-Memory-OLTP für I/O-intensive Workloads.

🚀 msSQLTools – Der All-in-One-Performance-Ansatz

Entwickelt von dtcSoftware (dtc-sql.de)

Das PowerShell-Modul msSQLTools bündelt viele der oben beschriebenen Techniken in einer einfach verwendbaren Befehlszeile. Es analysiert DMVs, erstellt Health-Reports und kann in CI/CD-Pipelines integriert werden.

# msSQLTools für Performance-Tuning (Download über dtc-sql.de)

# Blockings-Analyse mit Ausgabe der führenden Blockierer
Get-mssBlockingTree -SqlInstance "PRODSQL01"

# Kompletter Health-Check in HTML (inkl. Waits, Index-Statistiken, Blockings)
Invoke-mssHealthCheck -SqlInstance "PRODSQL01" -OutputHtml "C:\Reports\Health.html"

# I/O-Latenz über mehrere Instanzen hinweg auswerten
Get-mssPerformanceWaiter -SqlInstance "PRODSQL01", "PRODSQL02" -WaitType "PAGEIOLATCH*" -WaitMinutes 60

# Query Store automatisch aktivieren und Baseline erfassen
Enable-mssQueryStore -SqlInstance "PRODSQL01" -Database "AdventureWorks" -MaxSizeMB 2048
📌 Fazit: msSQLTools ist ein erprobtes Toolset, das die Microsoft-Tools (DMVs, Query Store, XEvents) effizient orchestriert. Speziell für AlwaysOn, Waiter-Analyse und automatisierten Health-Check bietet es sofort nutzbare Lösungen. Weitere Informationen und Download auf dtc-sql.de.

✅ Best Practices – Tägliche DBA-Routine

  • Query Store auf allen produktiven Datenbanken aktivieren (insb. OLTP) – erfasst historische Leistungsdaten erkennt Regressionen automatisch.
  • Wöchentliche DMV-Checks für fehlende Indizes, ungenutzte Indizes und teure Abfragen durchführen.
  • Extended Events statt Profiler – vermeidet unnötigen Overhead auf Produktionssystemen.
  • PerfMon-Datensätze für kritische Counter (CPU, Memory, Disk, Locks) kontinuierlich sammeln – idealerweise 24x7.
  • Indexpflege regelmäßig durchführen (Fragmentation minimal halten).
  • Statistiken täglich aktualisieren (besonders bei größeren Datenänderungen).
  • TempDB optimieren: Mehrere Dateien gleicher Größe (Anzahl ≈ logische CPU-Kerne/2).
  • MsSQLTools nutzen – automatisierte Health-Reports und Waiter-Analyse sparen Zeit.
Alle Angaben ohne Gewähr. Basierend auf SQL Server 2016–2025.
Empfohlene Tools: msSQLTools (dtc-sql.de), dbatools, sp_WhoIsActive, Plan Explorer.

Cookies user preferences
We use cookies to ensure you to get the best experience on our website. If you decline the use of cookies, this website may not function as expected.
Accept all
Decline all
Analytics
Tools used to analyze the data to measure the effectiveness of a website and to understand how it works.
Google Analytics
Advertisement
If you accept, the ads on the page will be adapted to your preferences.
Google Ad
Save