MySQL Slow Query Log einrichten und langsame Abfragen finden (Schritt für Schritt)
Du willst das MySQL Slow Query Log einrichten und langsame Abfragen finden? Diese Anleitung zeigt dir Schritt für Schritt, wie du das Log aktivierst, mit mysqldumpslow auswertest und mit EXPLAIN die Ursachen behebst.

Wenn deine Datenbank unter Last langsam wird, ist das MySQL Slow Query Log das wichtigste Werkzeug zur Fehlersuche. In dieser Anleitung lernst du, das MySQL Slow Query Log einrichten zu können, langsame Abfragen aufzuzeichnen, sie mit mysqldumpslow zu aggregieren und anschließend mit EXPLAIN gezielt zu analysieren. Die Anleitung richtet sich an Admins, Entwickler und Selfhosting-Nutzer, die MySQL oder MariaDB auf einem Linux-Server betreiben und konkret langsame MySQL Abfragen finden und beheben möchten. Alle Befehle funktionieren sowohl unter MySQL 8.x als auch unter MariaDB 10.x/11.x.
Kurzfassung: In my.cnf die Optionen slow_query_log=1, long_query_time=1 und slow_query_log_file setzen, den Dienst neu starten, das Log mit mysqldumpslow auswerten und die Top-Abfragen mit EXPLAIN analysieren. Häufigste Ursachen: fehlende Indizes, N+1-Queries und ineffiziente JOINs.
Was ist das Slow Query Log und warum brauchst du es?
Das Slow Query Log ist ein von MySQL/MariaDB geführtes Protokoll, das jede SQL-Abfrage aufzeichnet, deren Ausführung länger als ein definierter Schwellenwert (long_query_time) dauert. Statt zu raten, welche Abfrage deine Anwendung ausbremst, bekommst du messbare Fakten: Abfragetext, Ausführungszeit, Sperrzeit, untersuchte Zeilen und zurückgegebene Zeilen.
Damit ist das Log die Grundlage, um deine MySQL Performance zu optimieren. Typische Probleme sind fehlende Indizes, N+1-Queries (eine Anwendung feuert pro Schleifendurchlauf eine eigene Abfrage) und ineffiziente JOINs über große Tabellen. Optional kann das Log auch Abfragen erfassen, die gar keinen Index nutzen (log_queries_not_using_indexes).
Voraussetzungen
- Ein laufender MySQL-8.x- oder MariaDB-10.x/11.x-Server unter Linux (z. B. Debian/Ubuntu).
- Zugriff auf die Konfigurationsdatei (
/etc/mysql/my.cnfbzw. ein Drop-in unter/etc/mysql/conf.d/). - Einen MySQL-Benutzer mit
SUPER- bzw.SYSTEM_VARIABLES_ADMIN-Rechten (üblicherweiseroot). - Shell-/Root-Zugriff auf den Server, um den Dienst neu zu starten und Logdateien zu lesen.
- Eine Anwendung oder Test-Last, die echte Abfragen erzeugt.
Schritt 1: Aktuellen Status des Slow Query Logs prüfen
Bevor du etwas änderst, prüfst du, ob das Log bereits aktiv ist und wo es liegt.
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';
SHOW VARIABLES LIKE 'long_query_time';
SHOW VARIABLES LIKE 'log_queries_not_using_indexes';Steht slow_query_log auf OFF, ist das Log deaktiviert. Notiere dir den Pfad aus slow_query_log_file - Standard ist meist /var/lib/mysql/hostname-slow.log.
Schritt 2: MySQL Query Log aktivieren in der my.cnf
Um das MySQL Query Log aktivieren zu können, hinterlegst du die Optionen dauerhaft in der Konfiguration. Lege dafür idealerweise eine eigene Drop-in-Datei an.
sudo mkdir -p /var/log/mysql
sudo chown mysql:mysql /var/log/mysql
sudo nano /etc/mysql/conf.d/slow-query.cnfFüge folgenden Block ein. Der Abschnitt [mysqld] ist zwingend.
[mysqld]
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql/slow.log
log_queries_not_using_indexes = 1slow_query_log = 1- schaltet das Log ein.long_query_time = 1- Schwellenwert in Sekunden; Dezimalwerte wie0.5sind möglich.slow_query_log_file- Zieldatei des Logs.log_queries_not_using_indexes = 1- protokolliert zusätzlich Abfragen ohne Indexnutzung.
Speichere die Datei und starte den Dienst neu.
sudo systemctl restart mysql
# Bei MariaDB ggf.:
sudo systemctl restart mariadbSchritt 3: Slow Query Log zur Laufzeit aktivieren (ohne Neustart)
Willst du das Log temporär aktivieren, ohne den Dienst neu zu starten, setzt du die Variablen dynamisch. Wichtig: Den Pfad slow_query_log_file kannst du nur ändern, solange das Log noch OFF ist - setze ihn deshalb vor dem Einschalten.
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL long_query_time = 1;
SET GLOBAL log_queries_not_using_indexes = 'ON';
SET GLOBAL slow_query_log = 'ON';Wichtig: long_query_time wird nur für neue Verbindungen wirksam. Für die dauerhafte Lösung bleibt der Eintrag aus Schritt 2 maßgeblich.
Schritt 4: Last erzeugen und Verifikation
Jetzt prüfst du, ob tatsächlich Einträge geschrieben werden. Erzeuge zunächst künstlich eine langsame Abfrage.
SELECT SLEEP(2);Diese Abfrage dauert zwei Sekunden und überschreitet den Schwellenwert. Schau nun in die Logdatei.
sudo tail -n 30 /var/log/mysql/slow.logEin typischer Eintrag sieht so aus:
# Time: 2026-05-31T10:14:22.123456Z
# User@Host: app[app] @ localhost []
# Query_time: 2.000312 Lock_time: 0.000045 Rows_sent: 1 Rows_examined: 0
SET timestamp=1748686462;
SELECT SLEEP(2);Achte besonders auf Query_time und Rows_examined - ein großer Wert bei Rows_examined im Verhältnis zu Rows_sent ist ein Zeichen für einen fehlenden Index.
Schritt 5: Langsame MySQL Abfragen finden mit mysqldumpslow
Bei produktiver Last wächst das Log schnell. Statt manuell zu lesen, nutzt du mysqldumpslow - es aggregiert identische Abfragemuster und zeigt die teuersten Queries sortiert an.
mysqldumpslow -s at -t 10 /var/log/mysql/slow.log-s at- sortiert nach durchschnittlicher Query-Zeit. Alternativen:-s t,-s c,-s ar.-t 10- zeigt die Top 10.-g "PATTERN"- filtert auf einen Suchausdruck.-a- behält Zahlen/Strings statt sie zu abstrahieren.
Eine einzeln schnelle, aber sehr oft laufende Abfrage ist oft das eigentliche Problem (N+1):
mysqldumpslow -s c -t 10 /var/log/mysql/slow.logSchritt 6: EXPLAIN Abfrage analysieren
Hast du einen Kandidaten, untersuchst du den Ausführungsplan. Mit EXPLAIN kannst du die EXPLAIN Abfrage analysieren.
EXPLAIN SELECT * FROM orders WHERE customer_id = 42 AND status = 'open';type- Zugriffsart.ALList Tabellenscan (schlecht),ref/eq_refist Indexnutzung (gut).key- genutzter Index.NULLbedeutet kein Index.rows- geschätzte untersuchte Zeilen.Extra-Using filesort/Using temporarydeuten auf Optimierungspotenzial.
Für eine Baumsicht mit echten Werten nutzt du unter MySQL 8 EXPLAIN ANALYZE:
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 42 AND status = 'open';Fehlt ein Index, legst du ihn gezielt an:
CREATE INDEX idx_orders_customer_status ON orders (customer_id, status);Führe danach EXPLAIN erneut aus. type sollte nun ref sein und rows kleiner ausfallen.
Schritt 7: Updates, Wartung und Backup
Logrotation einrichten
Das Slow Query Log wächst dauerhaft. Viele Distributionen liefern /etc/logrotate.d/mysql-server mit. Nach einer Rotation muss MySQL in die neue Datei schreiben.
mysqladmin flush-logs
# oder gezielt:
mysqladmin flush-slow-logSchwellenwert anpassen
Nach der ersten Runde senkst du long_query_time schrittweise (z. B. auf 0.5). Deaktiviere log_queries_not_using_indexes wieder, sobald die Grundproblematik behoben ist.
Backup nicht vergessen
Bevor du Indizes auf produktiven Tabellen änderst, sichere die Datenbank:
mysqldump --single-transaction --routines --triggers \
-u root -p meinedatenbank > /backup/meinedatenbank_$(date +%F).sqlIndex-Änderungen sind umkehrbar (DROP INDEX), aber ein frisches Backup gehört vor jeden Eingriff am Schema.
Troubleshooting
- Das Log bleibt leer: Prüfe mit
SHOW VARIABLES LIKE 'slow_query_log';, ob esONist. Häufig wurde der Block unter[mysql]statt[mysqld]gesetzt. - Keine Schreibrechte: Das Verzeichnis gehört meist nicht dem MySQL-Benutzer. Setze
chown mysql:mysql /var/log/mysql. Bei AppArmor/SELinux muss der Pfad freigegeben sein. - Keine neuen Einträge: Nach einer Rotation schreibt MySQL in den alten Inode.
mysqladmin flush-logsbehebt das. - long_query_time ignoriert: Der Wert gilt nur für neue Verbindungen. Verbinde dich neu.
- mysqldumpslow nicht gefunden: Installiere unter Debian/Ubuntu
mysql-clientbzw.mariadb-client.
Häufige Fragen
Verlangsamt das Slow Query Log meine Datenbank?
Der Overhead ist gering, solange du in eine Datei loggst und einen sinnvollen Schwellenwert wählst. long_query_time = 0 protokolliert jede Abfrage und kann Leistung kosten. 0,5 bis 1 Sekunde ist ein guter Kompromiss.
Worin unterscheidet sich das Slow Query Log vom General Query Log?
Das General Query Log protokolliert jede Abfrage und ist nur für kurzes Debugging gedacht. Das Slow Query Log erfasst gezielt die langsamen Abfragen und ist das richtige Werkzeug für die dauerhafte Performance-Analyse.
Funktioniert das auch mit MariaDB?
Ja. MariaDB nutzt dieselben Variablennamen und liefert mysqldumpslow mit. Der Dienstname lautet mariadb, und EXPLAIN ANALYZE verhält sich in einigen Versionen abweichend von MySQL 8.
Wie finde ich N+1-Queries im Log?
Sortiere mysqldumpslow mit -s c nach Aufrufanzahl. Eine einzeln schnelle, aber tausendfach ausgeführte identische Abfrage ist das typische N+1-Muster und sollte gebündelt werden (Eager Loading oder JOIN).
Muss ich nach jeder Index-Änderung neu messen?
Ja. Führe nach jedem Eingriff erneut EXPLAIN aus und beobachte das Log über einen realen Lastzeitraum. Indizes beschleunigen Lesezugriffe, verlangsamen Schreibvorgänge minimal.
Fazit
Mit dem Slow Query Log hast du ein faktenbasiertes Werkzeug, um langsame MySQL Abfragen finden und beheben zu können. Der Ablauf: Log aktivieren, mit mysqldumpslow aggregieren, mit EXPLAIN prüfen, Indizes ergänzen. Wiederhole den Zyklus mit gesenktem Schwellenwert, und deine MySQL-Performance verbessert sich nachhaltig.
Weiterführende Anleitungen
Betreibst du auch PostgreSQL, lohnt sich ein Blick auf unseren Beitrag zum PostgreSQL 18.4 Sicherheitsupdate (CVE-2026-6473/6475). Weitere Beiträge findest du in unserer Kategorie Datenbanken.
Quellen
Die verwendeten Optionen und Befehle stammen aus der offiziellen Dokumentation: MySQL Reference Manual - The Slow Query Log, MySQL Reference Manual - mysqldumpslow sowie MariaDB Knowledge Base - Slow Query Log Overview.