SQL-Performance untersuchen? Metriken und Query Store prüfen
Ein Auslastungsdiagramm zeigt, wann Datenbankressourcen beschäftigt waren. Query Store ergänzt SQL-Anweisungen, Ausführungspläne und Laufzeitstatistiken, mit denen du beteiligte Abfragen untersuchen kannst. Vergleiche beide Ansichten für dasselbe Zeitfenster.
Verwende die Lab-Datenbank sqldb-cloudtrips aus Azure SQL Database erstellen oder erstelle sie erneut, falls sie gelöscht wurde. Der frühere Trip verwendet Basic mit DTUs. Melde dich im Query editor als SQL-Administrator an und erlaube deine aktuelle Client-IP in der Serverfirewall. Führe die Übung in der Lab-Datenbank aus.
Auslastung prüfen
Öffne sqldb-cloudtrips → Monitoring → Metrics. Wähle Last hour, eine Minute Granularität und vergleiche DTU percentage, CPU percentage, Data IO percentage und Log IO percentage. Average zeigt den Verlauf, Maximum hilft bei kurzen Spitzen. Bei einer vCore-Datenbank verwendest du die für deren Tarif verfügbaren CPU-/IO-Metriken.
DTUs bündeln Compute- und IO-Kapazität. Ein hoher DTU-Prozentsatz kann von einer einzelnen ausgelasteten Komponente bestimmt werden. Prüfe deshalb die Einzelmetriken, bevor du einen größeren Tarif auswählst. Eine ruhige Basic-Datenbank kann bei dieser kleinen Übung nahe null bleiben.
Screenshot 1: Datenbankauslastung mit ausgewähltem Zeitfenster und CPU-/IO-Messwerten.

Kleine Abfrage-Workload erfassen
Führe im Query editor aus:
SELECT actual_state_desc, query_capture_mode_desc
FROM sys.database_query_store_options;
Erwartet wird READ_WRITE. Notiere den Capture-Modus, normalerweise AUTO. Ist Query Store OFF, aktiviere ihn mit ALTER DATABASE CURRENT SET QUERY_STORE = ON;. Bei READ_ONLY prüfst du zuerst Konfiguration und verfügbaren Speicher.
Stelle für dieses kurze Lab den Capture-Modus auf ALL, damit auch eine kleine, günstige Abfrage erfasst wird. Erstelle eine eigene Testtabelle und führe die markierte Abfrage zehnmal aus:
ALTER DATABASE CURRENT SET QUERY_STORE (QUERY_CAPTURE_MODE = ALL);
IF OBJECT_ID(N'dbo.ct_monitor_probe', N'U') IS NULL
BEGIN
CREATE TABLE dbo.ct_monitor_probe (n int NOT NULL PRIMARY KEY);
INSERT dbo.ct_monitor_probe (n)
SELECT TOP (10000)
CONVERT(int, ROW_NUMBER() OVER (ORDER BY a.object_id, b.object_id))
FROM sys.all_objects AS a CROSS JOIN sys.all_objects AS b;
END;
DECLARE @i int = 0;
WHILE @i < 10
BEGIN
EXEC sys.sp_executesql N'/* CloudTrips_SQL_Monitor */
SELECT SUM(CONVERT(bigint, n)) AS total
FROM dbo.ct_monitor_probe WHERE n % 7 = 0;';
SET @i += 1;
END;
EXEC sys.sp_query_store_flush_db;
Stelle direkt danach den notierten Capture-Modus wieder her. Für den üblichen AUTO-Wert:
ALTER DATABASE CURRENT SET QUERY_STORE (QUERY_CAPTURE_MODE = AUTO);
Stelle ihn auch wieder her, falls die Workload fehlschlägt. War er zuvor ALL, NONE oder CUSTOM, verwende diesen ursprünglichen Wert. Die Übung erzeugt erkennbare Abfragehistorie; zehn kleine Abfragen können im Auslastungsdiagramm kaum sichtbar sein.
Abfrage-Performance untersuchen
Öffne Intelligent Performance → Query Performance Insight der Datenbank und wähle einen Zeitraum mit dem Test. Prüfe CPU, Ausführungsanzahl und Dauer. Wähle anschließend eine Abfrage, um ihren Text zu sehen. Für dieses Diagramm können einige Stunden erfasster Historie nötig sein.
Für eine unmittelbare Untersuchung führst du im Query editor aus:
SELECT TOP (10)
q.query_id,
p.plan_id,
SUM(rs.count_executions) AS executions,
CAST(SUM(rs.avg_duration * rs.count_executions)
/ NULLIF(SUM(rs.count_executions), 0) / 1000.0 AS decimal(18,2)) AS average_ms,
CAST(SUM(rs.avg_cpu_time * rs.count_executions)
/ NULLIF(SUM(rs.count_executions), 0) / 1000.0 AS decimal(18,2)) AS average_cpu_ms,
MAX(rs.last_execution_time) AS last_execution,
qt.query_sql_text
FROM sys.query_store_query_text AS qt
JOIN sys.query_store_query AS q ON q.query_text_id = qt.query_text_id
JOIN sys.query_store_plan AS p ON p.query_id = q.query_id
JOIN sys.query_store_runtime_stats AS rs ON rs.plan_id = p.plan_id
WHERE qt.query_sql_text LIKE N'/* CloudTrips_SQL_Monitor */%'
AND rs.last_execution_time >= DATEADD(hour, -1, SYSUTCDATETIME())
GROUP BY q.query_id, p.plan_id, qt.query_sql_text
ORDER BY executions DESC;
Die Berechnung gewichtet den Durchschnitt jedes Intervalls mit dessen Ausführungszahl und rechnet Mikrosekunden in Millisekunden um. Laufzeitstatistiken werden pro Intervall zusammengefasst; ein Filter auf die letzte Ausführung ist deshalb kein exakter Zeitfilter für einzelne Ereignisse.
Screenshot 2: Query-Store-Ergebnisse mit markierter Anweisung, Query-/Plan-IDs, Ausführungsanzahl und Dauer. Wenn Query Performance Insight bereits Daten anzeigt, kann dort dieselbe Untersuchung dargestellt werden.

Duration enthält verstrichene Wartezeit; CPU time misst Prozessorarbeit. Eine häufige günstige Abfrage kann insgesamt mehr Ressourcen verbrauchen als eine seltene teure. Untersuche Abfragetext, Pläne, Wartezeiten und Indizes, bevor du eine größere Datenbank auswählst.
Abschluss
Entferne die Testtabelle mit DROP TABLE IF EXISTS dbo.ct_monitor_probe; und prüfe den wiederhergestellten Capture-Modus. Lass Query Store für weitere Beobachtung aktiviert oder stelle den ursprünglich deaktivierten Zustand wieder her, falls du ihn nur für dieses Lab eingeschaltet hast. Behalte oder lösche die SQL-Lab-Ressourcen passend zu deinen weiteren SQL-Übungen.