...

MySQL Slow Query Log im Hosting analysieren: Optimierungstipps

MySQL Slow Query Log zeigt mir im Hosting, welche Abfragen Zeit fressen, wie oft sie auftreten und warum sie ausbremsen. Ich zeige dir konkrete Schritte, wie du den Log aktivierst, auswertest und Queries so umbaust, dass Seiten schneller laden und Serverressourcen effizienter arbeiten.

Zentrale Punkte

  • Aktivierung und Schwellenwerte sinnvoll setzen
  • Auswertung mit pt-query-digest und mysqldumpslow
  • Metriken interpretieren: Query_time, Lock_time, Rows_examined
  • Tuning durch Indizes, EXPLAIN und Rewrites
  • Automatisierung und Monitoring im Hosting

Was leistet das Slow Query Log im Hosting?

Hosting bedeutet geteilte Ressourcen, deshalb zählt jede Millisekunde pro Query. Ich nutze den Log, um Abfragen zu finden, die länger als einen definierten Grenzwert laufen, und sehe zu jeder Query Kennzahlen wie Query_time, Lock_time, Rows_sent und Rows_examined. Diese Zahlen zeigen mir, ob ein fehlender Index, ein ungünstiger Join oder ein Full Table Scan dahinter steckt. Gerade auf Servern mit mehreren Sites kann eine einzige schlechte Abfrage CPU und I/O stark beanspruchen. Ich priorisiere dann die Queries mit der höchsten Gesamtzeit, weil dort die größte Hebelwirkung auf Ladezeit und Serverlast liegt.

Aktivierung und sinnvolle Schwellenwerte

Starten kann ich runtime oder dauerhaft über my.cnf, je nach Zugriff im Hosting. Für schnelle Tests schalte ich den Log temporär ein und setze long_query_time auf einen Wert, der zu Traffic und Hardware passt. Ich gehe für stark genutzte Sites oft auf 0.1 Sekunden, beobachte aber die Loggröße, damit I/O nicht unnötig wächst. Wenn direkte Dateizugriffe limitiert sind, verwende ich die Performance Schema Optionen der MySQL Shell, um Berichte zu erzeugen. Nach dem Feintuning schreibe ich die finalen Einstellungen in die Konfigurationsdatei und starte den Dienst neu.

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log';
SET GLOBAL log_queries_not_using_indexes = 'ON';

SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

Dauerhaft setze ich Optionen wie log_throttle_queries_not_using_indexes und log_slow_admin_statements, damit der Log nützlich bleibt und nicht explodiert. Ich dokumentiere jeden Wert, zum Beispiel warum long_query_time 0.5 oder 0.1 Sekunden beträgt. So kann ich später fundiert nachschärfen. In Shared-Umgebungen spreche ich die Freischaltung oft mit dem Anbieter ab oder nutze dessen Panel. Jede Aktivierung verknüpfe ich mit einem Startdatum, um Effekte in Monitoring und Metriken sauber vergleichen zu können.

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow-query.log
long_query_time = 1
log_queries_not_using_indexes = 1
log_throttle_queries_not_using_indexes = 10
log_slow_admin_statements = 1

Slow-Log effektiv auswerten

Rohdaten sind laut, deshalb fasse ich sie mit pt-query-digest zusammen und sortiere nach Gesamtzeit über einen sinnvollen Zeitraum. So erkenne ich Muster, hoch variable Abfragen und Query-Familien, die nur durch Parameter variieren. Ich prüfe die Verteilung, nicht nur den Durchschnitt, denn Ausreißer erzeugen echte Nutzerprobleme. Für einen schnellen Überblick hilft mir mysqldumpslow, um die zehn langsamsten Gruppen zu sehen. Mehr Tiefe hole ich mir über Zeitfenster, Datenbank-Filter und einen Export in eine Textanalyse.

pt-query-digest /var/log/mysql/slow-query.log
pt-query-digest --since '24h' /var/log/mysql/slow-query.log
mysqldumpslow -s t -t 10 /var/log/mysql/slow-query.log

Nützlich ist zusätzlich ein Blick in andere Protokolle, wenn Anwendungs- oder PHP-Funktionen ins Spiel kommen. Dafür greife ich auf bestehende Log-Workflows zurück und bündele die Ergebnisse. Einen Einstieg bietet mir oft dieser Leitfaden: Logs analysieren. Ich synchronisiere die Zeitstempel, damit ich Spitzen im Traffic mit Query-Spitzen abgleiche. So sehe ich, ob Cache-Misses, Cronjobs oder Import-Jobs die Datenbank zur gleichen Zeit beanspruchen.

Metriken richtig interpretieren

Query_time zeigt mir die reine Laufzeit; ich priorisiere Queries über einer Sekunde zuerst. Lock_time weist auf Wartezeiten durch Sperren hin, die oft aus unnötig langen Transaktionen oder großen Batches stammen. Das Verhältnis Rows_examined zu Rows_sent verrät mir, ob Abfragen zu viele Zeilen sichten und Indizes fehlen. Wenn der Log viele „No index use“-Einträge enthält, setze ich das Throttling und schaue mir die betroffenen Tabellen genauer an. Wichtig bleibt, stets Ursache statt Symptom anzugehen: Ein Index auf die richtige Spalte schlägt jedes Hardware-Upgrade.

Metrik Was ich sehe Maßnahme
Query_time hoch Lange Laufzeit pro Ausführung EXPLAIN prüfen, Abfrage umschreiben, Index ergänzen
Lock_time hoch Wartezeit auf Sperren Transaktionen kürzen, Batch-Größe reduzieren, passende Isolation
Rows_examined ≫ Rows_sent Zu viel gescannt, wenig zurückgegeben Filterspalten indexieren, Sargability herstellen
Kein Index genutzt Full Table Scan Index erstellen, Ausdruck in WHERE vermeiden

Grenzwerte passe ich nach der ersten Woche an, damit ich nicht im Rauschen versinke. Ich senke long_query_time in Stufen, bis ich genug Treffer für systematische Verbesserungen habe. Jede Anpassung dokumentiere ich mit Datum und Grund. So bleibt die Auswertung fokussiert. Werthaltige Treffer ersparen mir später doppelte Arbeit.

Praxis: Query Tuning Schritt für Schritt

EXPLAIN ist mein Start, bevor ich Code ändere. Ich suche nach „type: ALL“, „rows“ mit großen Zahlen und „Using filesort“ oder „Using temporary“. Funktionen auf Spalten in WHERE oder JOIN verhindern oft Index-Nutzung. Stattdessen formuliere ich sargable Bedingungen und prüfe dann den neuen Plan. Jeder Schritt muss die Zeilenreduktion früh und zielgerichtet leisten.

EXPLAIN SELECT * FROM orders WHERE YEAR(created_at) = 2026;

-- Besser:
CREATE INDEX idx_orders_created ON orders(created_at);
SELECT * FROM orders
WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01';

JOINs optimiere ich, indem ich die Join-Reihenfolge und passende Indizes auf Join-Schlüsseln kontrolliere. Ich prüfe, ob ein Composite-Index WHERE + ORDER BY abdeckt, um Filesort zu vermeiden. LIMIT setze ich, wo nur eine Vorschau nötig ist. Ergebnis-Caching auf Applikationsebene spare ich mir für wiederholte, identische Abfragen mit geringer Änderungsrate. Eine tiefergehende Einführung in Indizes und Sperren findest du hier: Indizes und Locking.

Index-Strategien für CMS und Shops

WordPress, WooCommerce oder Shop-Systeme erzeugen typische Muster: viel Lesen, punktuell Schreiben, oft mit Meta- oder Produkt-Tabellen. Ich analysiere die häufigsten Routen – Startseite, Kategorie, Suche, Checkout – und lege Indizes gezielt auf Filter-, Sortier- und Join-Spalten. Covering-Indizes (z. B. (status, created_at, id)) sparen viele Rückgriffe auf die Tabelle. Für Suchen auf Präfixe nutze ich geeignete Indexformen oder Fulltext, statt LIKE ‚%wort%‘. Jede Indexänderung messe ich vor und nach dem Livegang mit denselben Lastprofilen.

Wachstum in Datenmengen prüfe ich über Kardinalität und Histogramme, damit ich nicht auf seltene Werte indexiere. Ich halte die Anzahl der Indizes schlank, um Schreiblast und Speicherbedarf im Griff zu behalten. Konsolidierte Composite-Indizes ersetzen mehrere Einzelindizes. Ich reguliere Autovacuum-ähnliche Aufgaben in MySQL durch regelmäßige Analyse und Rebuilds nur bei Bedarf. So bleibt der Optimizer verlässlich.

Servereinstellungen, Caching und Speicher

InnoDB Buffer Pool Größe bestimme ich anhand aktiver Datensätze und Indexgrößen, nicht nach Pauschalwerten. Ich erhöhe ihn, bis die Working Set Size weitgehend im Speicher liegt und die Page Miss Rate fällt. tmp_table_size und max_heap_table_size setze ich so, dass weniger temporäre Tabellen auf Disk landen. Für Schreibsicherheit und Latenz balanciere ich innodb_flush_log_at_trx_commit sinnvoll zur Anwendung. Auf Applikationsebene cache ich häufige Ergebnisse und nutze HTTP-Caching, damit die Datenbank weniger Anfragen sieht.

Hardware und Netzwerkeffekte beziehe ich in die Diagnose ein: Langsame Storage-I/O oder überlastete CPU spüren Queries sofort. Ich messe deshalb IO-wait parallel zu den Datenbankmetriken. Wer mehr Reserven braucht, plant vertikale oder horizontale Skalierung mit messbarem Ziel. Eine kompakte Übersicht zu Engpässen, Tuning und Ressourcen liefert dir dieser Leitfaden: Hardware und Cache. So stelle ich sicher, dass ich nicht blind am falschen Regler drehe.

Concurrency und Locking im Hosting

Lock_time wächst, wenn lange Transaktionen viele Zeilen berühren oder wenn Aufräumjobs zur Hauptzeit laufen. Ich kürze Schreibvorgänge, splitte große Updates in kleinere Batches und reduziere so die Haltezeit von Sperren. Geeignete Isolation Levels senken Konflikte, ohne Datenkonsistenz zu gefährden. Hotspots entlaste ich mit sekundären Indizes und passenden WHERE-Bedingungen, damit weniger Zeilen betroffen sind. Hintergrundjobs plane ich in verkehrsarmen Zeitfenstern, damit Nutzeraktionen Vorrang bekommen.

Deadlocks untersuche ich anhand wiederkehrender Muster: gleiche Tabellen, wechselnde Reihenfolge, identische Zeilen. Ich vereinheitliche die Zugriffsreihenfolge in Code und Stored Procedures. Retry-Logik mit Jitter löst temporäre Kollisionen. Wo möglich, isoliere ich teuerste Operationen in Job-Queues. So sinkt die Varianz spürbar und die gefühlte Performance steigt.

Automatisierte Alarme und Workflows

Routine schlägt Aktionismus: Ich werte den Log täglich oder wöchentlich aus, je nach Traffic und Release-Frequenz. Ein kleines Skript zählt neue Treffer in den letzten Minuten und schickt mir eine E-Mail, wenn der Schwellwert steigt. Zusätzlich generiere ich regelmäßige pt-query-digest Reports und halte die Top-10 immer im Blick. Release-Tage begleite ich mit engerem Monitoring. So erkenne ich Regressionen, bevor Nutzer sie merken.

#!/bin/bash
LOG_FILE="/var/log/mysql/slow-query.log"
THRESHOLD=100
RECENT_COUNT=$(awk -v cutoff="$(date -d '5 minutes ago' '+%Y-%m-%dT%H:%M')" '/^# Time:/ { if ($3 >= cutoff) count++ } END { print count+0 }' "$LOG_FILE")
if [ "$RECENT_COUNT" -gt "$THRESHOLD" ]; then
    echo "ALERT: $RECENT_COUNT slow queries" | mail -s "MySQL Alert" [email protected]
fi

Transparenz schaffe ich mit klaren Zuständigkeiten: Wer reagiert bei Peaks, wer passt Indizes an, wer testet Releases. Ich fasse Ergebnisse in kurzen Changelogs zusammen. So versteht jedes Teammitglied, warum eine Änderung kam und welche Wirkung sie hatte. Ein strukturierter Ablauf spart Zeit und verhindert Fehlalarme.

Fehlerbilder und schnelle Korrekturen

Full Table Scans lösen überproportional viel Last aus. Ich prüfe zuerst, ob ein passender Index auf der Filterspalte fehlt oder ob ein Ausdruck den Index blockiert. Hohe Lock_time beseitige ich, indem ich Transaktionen kürze und konkurrierende Operationen entzerre. Überlaufende Logs entschärfe ich mit log_throttle_queries_not_using_indexes und einem realistischen long_query_time. Jede Korrektur messe ich sofort gegen die ursprünglichen Zahlen, damit Erfolge sichtbar bleiben.

Storage-Engpässe erkenne ich an steigender IO-wait und hoher Disk-Latenz während Query-Spitzen. Ich reduziere dann unnötige Schreibvorgänge, etwa durch selteneres Aktualisieren unveränderlicher Felder. Wenn Tabellen wachsen, plane ich Archivierung oder Partitionsstrategien, damit Hot Data im Speicher bleibt. Für Admin-Statements im Peak schalte ich log_slow_admin_statements, um stille Kostentreiber zu identifizieren. Kleine, gezielte Fixes zahlen sich hier schneller aus als große Umbauten.

Besonderheiten in Managed- und Cloud-Umgebungen

Managed Hosting oder Cloud-Dienste begrenzen oft Dateizugriffe. In solchen Fällen stelle ich log_output auf TABLE und werte den Slow Log direkt aus der Datenbank aus. In MySQL 8.0 nutze ich zusätzlich SET PERSIST, um Einstellungen ohne direkten Zugriff auf my.cnf dauerhaft zu setzen. In Cloud-Parametergroups (z. B. bei verwalteten Diensten) trage ich die gleichen Variablen ein und plane ein Wartungsfenster für den Neustart.

-- Wenn erlaubt: Persistente Einstellungen ohne Neustart
SET PERSIST slow_query_log = ON;
SET PERSIST long_query_time = 0.5;
SET PERSIST log_output = 'TABLE';  -- Alternative zu FILE bei eingeschränktem Dateizugriff

-- Auswertung bei log_output=TABLE
SELECT start_time, user_host, query_time, lock_time, rows_sent, rows_examined, sql_text
FROM mysql.slow_log
ORDER BY query_time DESC
LIMIT 50;

Hinweis: Bei starkem Traffic kann log_output=FILE performanter sein, da Tabellenlogging zusätzlichen Overhead erzeugt. In restriktiven Umgebungen ist TABLE jedoch oft der einzige Weg. Ich setze dann engere Grenzwerte (z. B. min_examined_row_limit), um das Volumen kontrollierbar zu halten.

Rotation, Aufbewahrung und Datenschutz

Rotation verhindert, dass Logs die Platte füllen. Ich rotiere täglich oder nach Größe, komprimiere Altdateien und halte eine klare Aufbewahrungsstrategie ein (z. B. 14 Tage). Nach der Rotation triggere ich einen Log-Flush, damit MySQL sauber in die neue Datei schreibt. So bleiben Analyse und Betrieb stabil.

# /etc/logrotate.d/mysql-slow
/var/log/mysql/slow-query.log {
  daily
  rotate 14
  size 100M
  compress
  missingok
  notifempty
  create 640 mysql adm
  postrotate
    test -x /usr/bin/mysqladmin || exit 0
    /usr/bin/mysqladmin flush-logs
  endscript
}

Datenschutz ist Pflicht: Slow Logs können Parameterwerte enthalten. Ich limitiere den Zugriff strikt (Dateirechte, Gruppen) und prüfe, ob sensible Daten geloggt werden. Bei Bedarf arbeite ich mit Parameterbindung in der Anwendung, damit im Log keine personenbezogenen Klartexte auftauchen. Für Teamfreigaben teile ich bevorzugt aggregierte Reports statt Rohlogs.

Performance Schema und sys Schema nutzen

Performance Schema liefert Metriken auch ohne aktivierten Slow Log. Ich aktiviere die relevanten Consumer für Statements und werte dann die sys-Views aus. Vorteil: Ich sehe Top-Digests und Latenzverteilung nahezu in Echtzeit, gruppiert über ähnliche Queries hinweg.

-- Consumer für Statement-Historie aktivieren (soweit zur Laufzeit möglich)
UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME IN ('events_statements_history', 'events_statements_history_long');

-- Schneller Überblick über teure Query-Gruppen
SELECT schema_name, digest_text, count_star,
       ROUND(sum_timer_wait/1e12, 3) AS total_s,
       ROUND(avg_timer_wait/1e9, 3)  AS avg_ms,
       ROUND(max_timer_wait/1e9, 3)  AS pmax_ms
FROM sys.statement_analysis
ORDER BY sum_timer_wait DESC
LIMIT 10;

Kombination aus Slow Log (langsame Ausreißer) und Performance Schema (Breite, Häufigkeit) zeigt mir sowohl Einzelfälle als auch systematische Kostentreiber. Ich gleiche beide Sichten mit Trafficmustern ab, um priorisierte To-dos zu erstellen.

EXPLAIN ANALYZE und Optimizer Trace

EXPLAIN ANALYZE (ab MySQL 8.0.18) ergänzt Schätzungen um gemessene Zeiten. Ich vergleiche Zeilenabschätzungen mit tatsächlichen Werten und decke Fehleinschätzungen des Optimizers auf. Bei widersprüchlichen Plänen analysiere ich den Optimizer Trace, um zu sehen, warum ein Index nicht gewählt wurde.

-- Plan mit Messwerten
EXPLAIN ANALYZE
SELECT o.id, o.created_at
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE c.country = 'DE' AND o.status = 'paid'
ORDER BY o.created_at DESC
LIMIT 50;

-- Optimizer-Entscheidungen nachvollziehen
SET optimizer_trace="enabled=on";
SELECT ...;  -- zu untersuchende Abfrage
SELECT TRACE FROM information_schema.OPTIMIZER_TRACE\G
SET optimizer_trace="enabled=off";

Ergebnis: Wenn Schätzungen stark danebenliegen, aktualisiere ich Statistiken (ANALYZE TABLE), ergänze Histogramme oder forme Indizes/Abfragen so um, dass Selektivität früh greift.

Rewrite-Muster, die fast immer wirken

OR zu UNION ALL: Mehrere OR-Bedingungen auf verschiedenen Spalten verhindern oft Index-Nutzung. Ich trenne sie in zwei selektive Abfragen und vereinige die Ergebnisse, sofern sich Duplikate ausschließen lassen.

-- Vorher:
SELECT * FROM t WHERE a = ? OR b = ?;

-- Besser:
(SELECT * FROM t WHERE a = ?)
UNION ALL
(SELECT * FROM t WHERE b = ? AND a <> ?);

Paginierung: OFFSET/LIMIT wird mit wachsendem OFFSET teuer. Ich steige auf Keyset Pagination um und nutze einen geeigneten Sortierschlüssel (idealerweise indexiert und monoton).

-- Teuer:
SELECT id, title FROM posts ORDER BY created_at DESC LIMIT 50 OFFSET 5000;

-- Besser (Keyset):
SELECT id, title
FROM posts
WHERE created_at < :cursor
ORDER BY created_at DESC
LIMIT 50;

Composite-Indizes: Reihenfolge zählt. Ich sortiere Spalten im Index nach Selektivität und Query-Muster (WHERE-Filter zuerst, dann Sortierspalten). Ziel ist ein Covering-Index, der Filesort und Table-Lookups vermeidet.

Funktionale und generierte Indizes in MySQL 8

Ausdrücke in WHERE/JOIN blockieren häufig Indizes. In MySQL 8.0 indexiere ich gezielt Ausdrücke oder arbeite mit generierten Spalten, um Sargability herzustellen. Das lohnt sich besonders bei CASTs für numerische Metawerte oder JSON-Feldern.

-- Beispiel: numerische Sortierung auf Textfeld
ALTER TABLE product ADD COLUMN price_num DECIMAL(10,2)
  GENERATED ALWAYS AS (CAST(price AS DECIMAL(10,2))) STORED;
CREATE INDEX idx_product_price_num ON product(price_num);

-- Query ohne CAST und mit Index
SELECT * FROM product
WHERE price_num BETWEEN 10 AND 50
ORDER BY price_num;

Praxis: Ich teste, ob der neue Index wirklich zieht (EXPLAIN) und messe die Auswirkung im Slow Log. Generierte Spalten helfen auch, Präfixe oder normalisierte Varianten (LOWER(email)) effizient zu filtern.

CMS-/Shop-Patterns noch gezielter angehen

Meta-Tabellen (z. B. wp_postmeta) profitieren von kombinierten Indizes auf (post_id, meta_key) bzw. (meta_key, meta_value). Für häufige Filter auf meta_value_numeric nutze ich generierte Spalten wie oben, statt in jeder Query zu CASTen. Suchseiten beschleunige ich, indem ich Redundanzen ablege (Denormalisierung light) und den Lesezugriff indexfreundlich gestalte.

-- WordPress-typisch: schneller Zugriff auf Meta-Daten eines Beitrags
CREATE INDEX idx_postmeta_postid_metakey ON wp_postmeta(post_id, meta_key);
CREATE INDEX idx_postmeta_metakey_metavalue ON wp_postmeta(meta_key, meta_value(100));

Checkout-Pfade optimiere ich für minimale Sperrzeiten: kurze Transaktionen, nur die nötigen Zeilen, und Indizes exakt auf die verwendeten WHERE-Bedingungen. Für Reports plane ich asynchrone Aggregation (Zwischentabellen), damit Nutzerflows nicht ausgebremst werden.

Grenzen des Slow Logs und ergänzende Metriken

Viele kleine, schnelle Queries fallen im Slow Log nicht auf, summieren sich aber zur Last. Ich tracke deshalb auch Durchsatz (Queries/sec), 95./99.-Perzentile und den Anteil an Abfragen ohne Index. In Performance Schema oder APM-Tools erkenne ich N+1-Muster, die ich anschließend gezielt durch Joins, Batch-Ladevorgänge oder Caching auflöse.

Sampling ist sinnvoll, wenn Logs zu groß werden. Ich erhöhe long_query_time leicht oder setze min_examined_row_limit, um nur relevante Abfragen zu erfassen. Wichtig: Änderungen immer notieren, damit Zeitreihen vergleichbar bleiben.

Arbeitsweise: Vom Befund zur nachhaltigen Verbesserung

Baseline zuerst: Ich sichere mir einen Vorher-Report (Zeitfenster, Traffic, Konfiguration). Dann optimiere ich eine Query-Familie nach der anderen und vergleiche identische Zeitfenster. Jeder Fix landet dokumentiert im Repository (Was? Warum? Messwert vorher/nachher?). So bleiben Erfolge nachvollziehbar und regressionssicher.

# Grober Ablauf (Beispiel)
1) pt-query-digest --since '7d' slow-query.log > baseline.txt
2) Top 3 Query-Digests auswählen (nach Gesamtzeit)
3) EXPLAIN/EXPLAIN ANALYZE, Index- und Rewrite-Vorschläge ausarbeiten
4) Testdaten generieren, Lastprofil simulieren
5) Rollout mit Monitoring (engere Grenzwerte für 48h)
6) Vergleichsreport: pt-query-digest --since '48h' > after.txt
7) Ergebnis dokumentieren, nächste Tranche planen

Planstabilität beobachte ich über Zeit: Wenn sich Pläne ändern (neue Versionen, geänderte Statistiken), prüfe ich Histogramme, ANALYZE TABLE und die Indexlandschaft. Hints setze ich nur punktuell und dokumentiert, um nicht den Optimizer dauerhaft zu fesseln.

Zusammenfassung in klaren Schritten

Starten heißt: Log aktivieren, sinnvolle Grenzwerte setzen, erste Woche Daten sammeln. Danach fasse ich mit pt-query-digest zusammen, priorisiere nach Gesamtzeit und Varianz und wähle die Top-Treiber. Ich optimiere Queries mit EXPLAIN, sargablen Bedingungen und passenden Indizes und kontrolliere Locking durch kürzere Transaktionen. Serverseitig stelle ich Puffer, temporäre Tabellen und Flush-Strategien passend ein. Am Ende automatisiere ich Alarme und wiederhole den Zyklus regelmäßig – so bleibt die Datenbank schnell, auch wenn Traffic und Datenvolumen wachsen.

Aktuelle Artikel