Wenn’s langsam wird, fehlt meist ein Index
Abfragen brauchen Zeit.
Und wenn’s immer dieselbe Tabelle ist, dann liegt’s meist an den fehlenden Indizes.
Ohne passenden Index scannt SQL Server die komplette Tabelle.
Und das bei jeder Ausführung.
Gerade in KMU-Systemen sehe ich oft:
300.000 Zeilen, keine Indizes außer dem Primary Key.
Und dann wundert man sich, warum der Bericht 40 Sekunden braucht.
So finde ich fehlende Indizes – systematisch
SQL Server merkt sich, welche Spalten gerne gefiltert werden.
Und welche Spalten häufig gelesen werden.
Er schlägt Dir sogar Indizes vor. Du musst sie nur abholen.
Übersicht der empfohlenen Indizes
SELECT
migs.user_seeks + migs.user_scans AS anfragen,
migs.avg_total_user_cost * (migs.user_seeks + migs.user_scans) AS gewichtung,
mid.statement AS tabelle,
mid.equality_columns,
mid.inequality_columns,
mid.included_columns
FROM sys.dm_db_missing_index_group_stats AS migs
JOIN sys.dm_db_missing_index_groups AS mig ON migs.group_handle = mig.index_group_handle
JOIN sys.dm_db_missing_index_details AS mid ON mig.index_handle = mid.index_handle
WHERE migs.user_seeks + migs.user_scans > 10
ORDER BY gewichtung DESC;
So bekommst Du:
- welche Spalten fehlen im Index
- wie oft wird danach gesucht
- welche Spalten gelesen werden (für
INCLUDE
) - wie teuer ist die aktuelle Abfrage
Index-Vorschlag erzeugen
-- Beispiel:
CREATE NONCLUSTERED INDEX ix_kunde_plz_ort
ON dbo.kunde (plz, ort)
INCLUDE (name, telefon);
Achte auf die Reihenfolge:
Spalten mit Gleichheitsbedingung zuerst.
Dann Ungleichheitsbedingungen.
Dann INCLUDE
.
Wichtige Faustregeln
Problem | Lösungsidee |
---|---|
WHERE ohne Index | Spalte als Schlüssel in Index nehmen |
JOIN wird gescannt | Join-Spalte indexieren |
Sortierung zu langsam | Index auf ORDER BY-Spalte(n) |
Spalten oft gelesen | INCLUDE verwenden |
Beispiel: Bericht mit Filtersuche
SELECT name, ort, plz
FROM dbo.kunde
WHERE ort = 'Hamburg'
ORDER BY name;
Passender Index:
CREATE NONCLUSTERED INDEX ix_kunde_ort_name
ON dbo.kunde (ort)
INCLUDE (name, plz);
Ergebnis: kein Scan, keine Sortierung, direkter Zugriff.
Vorsicht: Keine Indexpest erzeugen
Zu viele Indizes = langsames INSERT/UPDATE
Deshalb:
- nicht mehr als 4–6 Indizes pro Tabelle
- nur das indexieren, was oft genutzt wird
- überlappende Indizes zusammenfassen
- alte, ungenutzte Indizes löschen
SELECT
OBJECT_NAME(s.object_id) AS tabelle,
i.name AS indexname,
i.type_desc,
user_seeks, user_scans, user_lookups, user_updates
FROM sys.dm_db_index_usage_stats AS s
JOIN sys.indexes AS i ON s.object_id = i.object_id AND s.index_id = i.index_id
WHERE database_id = DB_ID()
AND user_seeks + user_scans + user_lookups = 0
AND user_updates > 0;
So findest Du Indizes, die nie genutzt, aber ständig aktualisiert werden.
Mein Fazit
Fehlende Indizes sind wie fehlende Wegweiser.
Du findest den Datensatz – aber nur mit Mühe.
Wenn Du regelmäßig langsame Queries hast, lohnt sich ein Blick in die DMVs.
SQL Server zeigt Dir den Weg – Du musst nur folgen.
Wenn Du willst, optimier ich mit Dir gemeinsam die zehn langsamsten Abfragen.
Meist genügen drei neue Indizes – und plötzlich läuft’s.
No responses yet