Datenbank ist langsam
Symptom
Anwendungsweite Langsamkeit; Abfragen dauern viel länger als üblich, und Benutzer beschweren sich.
1. Kläre zuerst, was genau langsam ist
Ist alles langsam oder nur eine bestimmte Abfrage/Maske? Wann hat es begonnen, und fällt das mit einem Deployment/Patch/Datenwachstum zusammen? Betrifft es das ganze System oder eine einzelne DB? So grenzt du die Suche auf eine Achse ein: CPU, I/O, Sperren oder Planänderung.
2. Aktive Sessions und Wait Events prüfen
Was läuft gerade, und was wartet? Ein dominierendes Wait Event (I/O, Lock, Log) zeigt auf den Engpass.
Oracle
SELECT sid, username, status, event, sql_id FROM v$session WHERE status='ACTIVE' AND type='USER';PostgreSQL
SELECT pid, state, wait_event_type, wait_event, query FROM pg_stat_activity WHERE state='active';MySQL
SELECT id, user, command, time, state, info FROM information_schema.processlist WHERE command<>'Sleep' ORDER BY time DESC;SQL Server
SELECT session_id, status, wait_type, wait_time, blocking_session_id FROM sys.dm_exec_requests WHERE session_id IN (SELECT session_id FROM sys.dm_exec_sessions WHERE is_user_process = 1);MongoDB
db.currentOp({ active: true, secs_running: { $gt: 1 } })Redis
SLOWLOG GET 103. Auf Blockierungen prüfen
Die häufigste Ursache für Langsamkeit ist eine Session, die andere blockiert. Finde die blockierende Session und ermittle den Anfang der Kette.
Oracle
SELECT blocking_session, sid, seconds_in_wait, event FROM v$session WHERE blocking_session IS NOT NULL;PostgreSQL
SELECT pid, pg_blocking_pids(pid) AS blocked_by, query FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid))>0;MySQL
SELECT * FROM sys.innodb_lock_waits\GSQL Server
SELECT session_id, blocking_session_id, wait_type FROM sys.dm_exec_requests WHERE blocking_session_id<>0;4. Die teuersten Abfragen ermitteln
Finde die 10 Abfragen mit dem höchsten Ressourcenverbrauch. Meist stammen 90 % des Problems von einer Handvoll Abfragen.
Oracle
SELECT sql_id, elapsed_time/1e6 sec, executions, sql_text FROM v$sql ORDER BY elapsed_time DESC FETCH FIRST 10 ROWS ONLY;PostgreSQL
SELECT calls, total_exec_time, mean_exec_time, query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;MySQL
SELECT digest_text, count_star, sum_timer_wait/1e12 sec FROM performance_schema.events_statements_summary_by_digest ORDER BY sum_timer_wait DESC LIMIT 10;SQL Server
SELECT TOP 10 total_elapsed_time/execution_count avg_us, execution_count, SUBSTRING(t.text,1,200) FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t ORDER BY total_elapsed_time DESC;5. Plan der verdächtigen Abfrage untersuchen
Hole dir EXPLAIN für die langsame Abfrage. Achte auf Full Table Scans, fehlende Indizes, schlechte Join-Reihenfolge oder veraltete Statistiken. Hat sich der Plan plötzlich geändert, erwäge, Statistiken zu sammeln.
Oracle
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('&sql_id', NULL, 'ALLSTATS LAST'));PostgreSQL
EXPLAIN (ANALYZE, BUFFERS) <query>;MySQL
EXPLAIN ANALYZE <query>;SQL Server
SET STATISTICS PROFILE ON; <query>; SET STATISTICS PROFILE OFF;MongoDB
db.my_collection.find({...}).explain('executionStats') // COLLSCAN or IXSCAN?6. Systemressourcen prüfen
Prüfe auf OS-Ebene CPU, I/O-Wartezeit (iowait), Speicher und Plattenbelegung. Prüfe die Cache Hit Ratio; ist sie niedrig, liegt eventuell ein Speicherengpass vor. Das Problem kann auch außerhalb der DB liegen (volle Platte, Noisy-Neighbor-VM).
7. Entscheiden: schnelle oder dauerhafte Lösung
Für sofortige Entlastung: die ausufernde Abfrage beenden, den fehlenden Index anlegen, Statistiken sammeln. Für eine dauerhafte Lösung: Abfrage/Index neu entwerfen, Speichereinstellungen korrigieren, Planstabilität sicherstellen (Baseline/Hint).