WordPress-Datenbank aufräumen und optimieren
Kurz gesagt
Der größte Bremsfaktor in der WordPress-Datenbank sind aufgeblähte autoload-Daten in der Tabelle wp_options, die bei jedem einzelnen Seitenaufruf automatisch mitgeladen werden – oft Reste deinstallierter Plugins. Revisionen, Transients, Papierkorb und verwaiste Metadaten machen die Datenbank zwar kleiner und Backups schneller, wirken sich auf die Ladezeit aber meist geringer aus. Entscheidend ist, vor und nach dem Aufräumen zu messen, statt blind ein Plugin laufen zu lassen – und vorher immer ein Backup anzulegen.
Die Datenbank ist das Gedächtnis deiner WordPress-Seite – und sie wächst mit jedem Beitrag, jedem Plugin und jeder gespeicherten Einstellung. Mit der Zeit sammelt sich Ballast an, der jeden Seitenaufbau minimal verzögert und Backups aufbläht. Das Aufräumen lohnt sich, wenn man weiß, wo man ansetzt, und vorher wie nachher misst, statt blind ein Plugin klicken zu lassen.
Hinweis zu allen Snippets: Als Tabellenpräfix steht überall
wp_. Dein Präfix steht in derwp-config.php($table_prefix) und kann anders lauten, etwawp7x_. Ersetze es entsprechend, sonst läuft die Abfrage ins Leere oder meldet einen Fehler. Der Generator weiter unten setzt dein Präfix automatisch ein.
Wo sich der Ballast ansammelt
Diese Stellen sind fast immer betroffen:
- Beitragsrevisionen: WordPress speichert jede Zwischenversion. Bei langen Texten summiert sich das schnell auf das Vielfache des eigentlichen Inhalts.
- Transients: zwischengespeicherte, eigentlich temporäre Daten von Plugins, die nicht immer sauber ablaufen und dann als Leichen liegen bleiben.
- autoload-Daten in
wp_options: Optionen, die als autoload gelten, werden bei jedem Seitenaufruf geladen. Verlassene Plugins hinterlassen hier oft große Datenmengen. Das ist der wichtigste Punkt. - Papierkorb und Spam: gelöschte Beiträge im Papierkorb, Spam- und abgelehnte Kommentare samt ihren Metadaten.
- Verwaiste Metadaten:
postmeta- undcommentmeta-Einträge, deren Beitrag oder Kommentar längst gelöscht ist. - Job-Tabellen von Plugins: bei WooCommerce vor allem die Tabellen des Action Schedulers.
Erst messen: Größe der Datenbank und der Tabellen
Bevor du löschst, schau dir die Lage an. Mit WP-CLI bekommst du die Gesamtgröße und die Größe pro Tabelle in einem Befehl:
wp db size --tables --size_format=mb
Ohne WP-CLI geht das in phpMyAdmin oder per SQL. Die Abfrage listet die fünfzehn größten Tabellen deiner Installation, data_free ist der Platz, den InnoDB intern freigehalten hat:
-- Präfix wp_ ggf. anpassen (im LIKE-Muster steckt es auch)
SELECT table_name,
ROUND((data_length + index_length) / 1024 / 1024, 1) AS mb,
ROUND(data_free / 1024 / 1024, 1) AS frei_mb
FROM information_schema.TABLES
WHERE table_schema = DATABASE() AND table_name LIKE 'wp\_%'
ORDER BY (data_length + index_length) DESC
LIMIT 15;
Notiere dir die Werte. Sie sind dein Vorher-Stand. Meist stehen wp_posts, wp_postmeta und wp_options oben, bei Shops kommen die Action-Scheduler-Tabellen dazu.
wp_options optimieren: der größte einzelne Hebel
Die Tabelle wp_options ist die Schaltzentrale deiner Installation: von der Site-URL bis zu den Einstellungen jedes Plugins landet hier alles. Genau deshalb zahlt sich Aufräumen hier am stärksten aus. Dieser Abschnitt geht Schritt für Schritt durch, was du wissen und tun musst.
Was autoload in wp_options bedeutet
Jede Zeile in wp_options hat eine Spalte autoload. Beim Start eines Requests lädt WordPress alle Optionen, die als autoload markiert sind, in einem Rutsch in den Speicher. So sind Dinge wie Site-URL oder aktive Plugins sofort verfügbar, ohne dass jede Option einzeln abgefragt werden muss. Das Problem entsteht, wenn Plugins große Datenmengen in autoload-Optionen ablegen: Dann schleppt jeder Seitenaufruf, auch jeder Admin-Klick und jeder Cron-Lauf, diese Daten mit.
Seit WordPress 6.6 kennt die Spalte mehr als yes und no. Nach der WordPress-Entwicklerdoku und dem Core-Blog gelten diese Werte:
| Wert | Bedeutung |
|---|---|
on |
ausdrücklich auf autoload gesetzt |
off |
ausdrücklich nicht autoload |
auto |
Standard, wenn nichts angegeben wurde; wird derzeit geladen |
auto-on |
von WordPress als autoload eingestuft |
auto-off |
von WordPress als nicht autoload eingestuft |
yes / no |
alte Werte; sie bleiben in bestehenden Datenbanken erhalten und zählen als on bzw. off |
Welche Werte tatsächlich geladen werden, liefert die Funktion wp_autoload_values_to_autoload() (seit 6.6): standardmäßig yes, on, auto-on und auto. Wer wie früher nur nach autoload = 'yes' filtert, übersieht auf neueren Installationen also einen Teil der geladenen Optionen. Außerdem gilt seit 6.6: Eine Option über 150.000 Bytes wird ohne ausdrückliche Anweisung nicht mehr automatisch geladen (Filter wp_max_autoloaded_option_size). Alte Einträge werden dadurch nicht umgeschrieben, sie behalten ihren Wert.
Die autoload-Größe messen
Die Gesamtgröße aller geladenen Optionen in MB, mit allen vier Werten, die WordPress seit 6.6 lädt:
-- Tabellenpräfix wp_ ggf. anpassen
SELECT ROUND(SUM(LENGTH(option_value)) / 1024 / 1024, 2) AS autoload_mb,
COUNT(*) AS anzahl
FROM wp_options
WHERE autoload IN ('yes', 'on', 'auto-on', 'auto');
Und die zwanzig größten Einträge:
SELECT option_name, autoload,
ROUND(LENGTH(option_value) / 1024, 1) AS kb
FROM wp_options
WHERE autoload IN ('yes', 'on', 'auto-on', 'auto')
ORDER BY LENGTH(option_value) DESC
LIMIT 20;
Mit WP-CLI geht es kürzer. Laut WP-CLI-Doku liefert --format=total_bytes die Gesamtgröße der autoload-Optionen, size_bytes ist ein zusätzliches Feld:
wp option list --autoload=on --format=total_bytes
wp option list --autoload=on --fields=option_name,size_bytes --format=csv | sort -t, -k2 -nr | head -20
Beachte: Die WP-CLI-Doku nennt für --autoload die Werte on und off. Ob dabei alle autoload-Varianten erfasst werden, hängt von deiner WP-CLI-Version ab. Prüfe deshalb zur Sicherheit einmal mit der SQL-Abfrage oben gegen.
Die Site-Health-Prüfung
Seit WordPress 6.6 gibt es in Werkzeuge → Website-Zustand eine Prüfung zu autoload-Optionen. Laut Entwicklerdoku (WP_Site_Health::get_test_autoloaded_options()) steht sie bei 800.000 Bytes autoload-Gesamtgröße auf „kritisch”; die Schwelle lässt sich über den Filter site_status_autoloaded_options_size_limit ändern. Als Meldung erscheint „Autoloaded options could affect performance”. Das ist eine grobe Warnschwelle. Deine Seite kann schon darunter spürbar leiden, wenn ein einzelnes Plugin den Löwenanteil belegt, und sie kann darüber noch ordentlich laufen. Die Liste der größten Einträge aus der Abfrage oben sagt mehr als die Ampel.
Verwaiste Optionen alter Plugins erkennen
In der Liste der größten Einträge suchst du nach Optionen, die keinem aktiven Plugin oder Theme mehr zuzuordnen sind. Hinweise:
- Der Optionsname beginnt oft mit dem Plugin-Kürzel (
elementor_,wpseo_,jetpack_). Taucht ein Kürzel auf, dessen Plugin längst entfernt ist, ist das ein Kandidat. - Plugins legen Debug-Logs, API-Antworten oder große Konfigurations-Arrays gern in Optionen ab. Das erkennst du an der Größe im KB-Bereich bei Namen wie
*_cache,*_logoder*_data. - Lösche nie nach dem Namen allein. Suche den Optionsnamen im Code (
wp-content/plugins,wp-content/themes, notfalls pergrep -r). Wird er dort noch verwendet, gehört die Option zu etwas, das aktiv ist. - Theme-Mods (
theme_mods_<themename>) sind keine Plugin-Leichen. Sie gehören zu einem Theme, das installiert ist, auch wenn es gerade nicht aktiv ist.
Transients erkennen und sicher bereinigen
Transients sind Optionen mit Verfallsdatum. In der Datenbank erscheinen sie als Paar: _transient_<name> für den Wert und _transient_timeout_<name> für den Zeitstempel des Ablaufs. Bei Site-Transients heißt das Präfix _site_transient_. Laut Transients-Doku löscht WordPress abgelaufene Transients nur gelegentlich selbst, sie können sich also anhäufen. Eine Besonderheit: Mit einem persistenten Objekt-Cache (Redis, Memcached) liegen Transients im Cache und gar nicht in der Datenbank. Dann ist in wp_options meist wenig zu holen, dafür kann der Cache selbst wachsen. Mehr dazu im Artikel zum Caching in WordPress.
Abgelaufene Transients zählen, bevor du etwas löschst:
-- Tabellenpräfix wp_ ggf. anpassen
SELECT COUNT(*) AS abgelaufen
FROM wp_options
WHERE option_name LIKE '\_transient\_timeout\_%'
AND CAST(option_value AS UNSIGNED) < UNIX_TIMESTAMP();
Das Löschen übernimmt am saubersten WP-CLI, weil es WordPress’ eigene Funktionen nutzt statt rohes SQL:
wp transient delete --expired
wp transient delete --all entfernt dagegen alle Transients, auch gültige. Das ist ungefährlich, weil Plugins ihre Transients bei Bedarf neu erzeugen, kostet aber kurzzeitig Performance, bis die Caches wieder gefüllt sind. Für den Normalfall reicht --expired. Unter Multisite kommt --network für die Site-Transients dazu.
Autoload sicher umstellen
Große Optionen, die du nicht löschen willst, stellst du auf „nicht automatisch laden”. Der Eintrag bleibt erhalten, WordPress lädt ihn nur noch, wenn Code ihn tatsächlich anfragt. Mit WP-CLI (laut Doku ab WP-CLI 2.8.0, akzeptiert werden on, off, yes und no):
wp option set-autoload name_der_option off
Per SQL funktioniert das ebenfalls. Ich verwende hier no, weil dieser Wert auf allen WordPress-Versionen verstanden wird und seit 6.6 wie off behandelt wird:
-- Tabellenpräfix wp_ ggf. anpassen
UPDATE wp_options SET autoload = 'no' WHERE option_name = 'name_der_option';
Das ist der sichere erste Schritt, weil sich die Änderung mit on bzw. yes jederzeit zurücknehmen lässt. Es gibt allerdings einen Haken: Ein Plugin kann beim nächsten Update oder Speichern den Wert wieder auf autoload setzen, und eine Option, die tatsächlich bei jedem Request gebraucht wird, wird danach einzeln nachgeladen. Prüfe deshalb nach der Umstellung, ob die Seite und der Admin-Bereich normal funktionieren und ob die Größe wirklich gesunken ist.
Löschen: erst mit Backup
Optionen, deren Plugin nachweislich nicht mehr installiert ist, kannst du entfernen:
wp option delete name_der_option
Lege vorher ein Backup an, denn Löschen ist endgültig. Wie du dabei vorgehst, steht im Artikel zu WordPress-Backups. Zwischen „umgestellt auf off” und „gelöscht” liegt am besten ein paar Tage Beobachtungszeit.
Der Effekt
Sinkt die autoload-Größe aus der Abfrage oben von mehreren MB auf wenige hundert KB, spürt das jeder einzelne Seitenaufruf, ganz ohne Caching-Plugin. Bewegt sie sich kaum, lag der Engpass woanders.
Weitere Baustellen gezielt aufräumen
Revisionen und Papierkorb
Revisionen begrenzt du dauerhaft in der wp-config.php:
define( 'WP_POST_REVISIONS', 5 );
So bleiben pro Beitrag höchstens fünf Revisionen erhalten. false schaltet sie komplett ab (laut WordPress-Doku zu wp-config.php). Vorhandene Revisionen zählst du so:
SELECT COUNT(*) FROM wp_posts WHERE post_type = 'revision';
Zum Löschen taugt WP-CLI besser als ein DELETE auf wp_posts, weil WordPress dabei die zugehörigen Metadaten mit entfernt. Laut WP-CLI-Doku überspringt --force den Papierkorb:
wp post delete $(wp post list --post_type=revision --format=ids) --force
Der Papierkorb leert sich laut Doku nach 30 Tagen von selbst (EMPTY_TRASH_DAYS, Standard 30). Mit 0 schaltest du ihn ab, und dann gibt es bei „Endgültig löschen” keine Rückfrage mehr, also nur mit Bedacht. Die automatische Entsorgung von Kommentar-Spam nach 15 Tagen greift zusätzlich.
Verwaiste Metadaten in wp_postmeta
wp_postmeta wächst oft stärker als jede andere Tabelle, weil Plugins pro Beitrag viele Zeilen anlegen. Eine Zeile ist verwaist, wenn ihr Beitrag nicht mehr existiert. Erst zählen:
SELECT COUNT(*) AS waisen
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
Dann, mit Backup, löschen:
DELETE pm
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
Die Anzahl der Zeilen sagt nichts über ihre Größe. Schau in der Tabellenliste von oben, ob wp_postmeta überhaupt auffällt, bevor du viel Zeit hineinsteckst. Dasselbe Muster gilt für wp_commentmeta (Spalte comment_id gegen wp_comments).
Action-Scheduler-Tabellen bei WooCommerce
Der Action Scheduler, der in WooCommerce steckt, speichert seine Jobs laut Dokumentation in eigenen Tabellen mit dem Präfix actionscheduler_ (also etwa wp_actionscheduler_actions und wp_actionscheduler_logs). Wenn die Tabellenliste dort zweistellige MB-Werte zeigt, lohnt ein Blick auf die Ursache: Meist fehlschlagende oder sehr häufig wiederholte Jobs, nicht fehlende Wartung. Wer nur die Zeilen löscht, ohne den Job zu reparieren, hat das Problem bald wieder. Was bei Shops sonst auf die Performance wirkt, steht in WooCommerce schneller machen.
Indizes und Speicher-Engine
Zwei Punkte, die weniger oft das Problem sind, als man annimmt:
- Speicher-Engine: Moderne WordPress-Installationen laufen auf InnoDB, das ist in MySQL 8.4 die Standard-Engine. Alte Installationen haben mitunter noch MyISAM-Tabellen. Die Engine pro Tabelle zeigt
SELECT table_name, engine FROM information_schema.TABLES WHERE table_schema = DATABASE();. Eine Umstellung (ALTER TABLE wp_xyz ENGINE=InnoDB;) gehört in die Hände von jemandem, der ein Backup und ein Wartungsfenster hat. - Indizes: Die Core-Tabellen bringen ihre Indizes mit. Fehlende Indizes sind eher ein Thema bei eigenen Plugin-Tabellen. Eine langsame Abfrage prüfst du mit
EXPLAIN, bevor du irgendeinen Index anlegst. Ein Index auf Verdacht kostet Schreib-Performance und hilft selten.
Die SQL-Abfragen für Revisionen, Transients, Spam und Metadaten erzeugt dir auch der Generator mit deinem Tabellen-Präfix, erst zählen, dann löschen:
SQL-Generator
WordPress-Datenbank aufräumen
Zielgrößen wählen, messen oder aufräumen. Alles läuft in deinem Browser – nichts wird automatisch ausgeführt.
Bevor du fortfährst: Erstelle zuerst ein Backup der Datenbank. Führe das SQL über phpMyAdmin oder wp db query aus. DELETE-Anweisungen lassen sich nicht rückgängig machen.
Deine Eingaben verlassen den Browser nicht. Das SQL wird lokal per JavaScript erzeugt.
Auch als eigenständige Seite mit allen Anleitungen: SQL-Generator.
Tabellen-Overhead entfernen: was OPTIMIZE TABLE tut
Nach dem Löschen bleibt reservierter, aber ungenutzter Speicher zurück. OPTIMIZE TABLE holt ihn zurück, und was dabei passiert, hängt von der Engine ab:
- InnoDB: Laut MySQL-Doku wird
OPTIMIZE TABLEaufALTER TABLE ... FORCEabgebildet. Die Tabelle wird neu aufgebaut, die Index-Statistiken werden aktualisiert und ungenutzter Platz im Clustered Index wird freigegeben. Die Doku nennt auch den Online-Charakter: Ein exklusiver Tabellen-Lock wird nur kurz in der Vorbereitungs- und der Commit-Phase gehalten. Möglicherweise siehst du die Meldung „Table does not support optimize, doing recreate + analyze instead”. Das ist bei InnoDB normal und kein Fehler. - MyISAM: Hier defragmentiert
OPTIMIZE TABLEdie Datendatei und gibt Platz aus gelöschten Zeilen frei, besonders sinnvoll nach dem Löschen großer Teile.
Die Wirkung ist begrenzt: Es wird Platz auf der Platte frei und Backups werden kleiner. Die Seitengeschwindigkeit ändert das selten messbar. In phpMyAdmin geht es per Klick auf „Tabelle optimieren”, mit WP-CLI mit wp db optimize (laut Doku läuft dahinter mysqlcheck --optimize). Plane das außerhalb der Stoßzeiten.
Wichtig: Vor jedem Eingriff in die Datenbank ein Backup. Eine falsch gelöschte Option kann eine Seite lahmlegen.
Nachher messen
Führe dieselben Abfragen wie am Anfang noch einmal aus: die Tabellengrößen, die autoload-Größe und die Liste der größten Optionen. Vergleiche mit deinen notierten Werten und wirf einen Blick auf die Ladezeit (PageSpeed Insights, besser noch die Antwortzeit des Servers im Netzwerk-Tab, weil sie die Datenbank direkter widerspiegelt). Nur so weißt du, ob das Aufräumen wirklich etwas gebracht hat und nicht nur ein gutes Gefühl war. Wenn die autoload-Größe von mehreren MB auf einen Bruchteil sinkt, hast du echten Ballast entfernt. Bewegt sie sich kaum, lag das Problem woanders, etwa bei Plugins, Hosting oder fehlendem Caching.
Wie oft, und wie es dauerhaft sauber bleibt
Einmaliges Aufräumen verpufft, wenn sich der Ballast gleich wieder ansammelt. Nachhaltiger ist die Kombination: Revisionen dauerhaft begrenzen, Spam automatisch entsorgen lassen, abgelaufene Transients regelmäßig entfernen und nach dem Entfernen größerer Plugins gezielt deren autoload-Reste prüfen. Für die meisten Seiten reicht dann ein bis zwei Mal im Jahr ein bewusster Blick. Genau so ein regelmäßiger Check gehört bei uns zur WordPress-Wartung.
Eine komplett unerreichbare Datenbank ist ein eigenes Thema → Datenbankverbindung fehlgeschlagen. Ansonsten ist die Datenbank einer der Hebel, die in die Core Web Vitals einzahlen, neben Caching.
Du willst wissen, was deine Datenbank wirklich ausbremst, ohne selbst SQL zu schreiben? Schreib uns kurz – wir messen, räumen sicher auf und zeigen dir den Unterschied.
Häufige Fragen
Bringt das Aufräumen der WordPress-Datenbank wirklich Performance?
Es kommt darauf an, wie viel Ballast sich angesammelt hat. Der wirksamste Hebel sind aufgeblähte autoload-Daten, die WordPress bei jedem einzelnen Seitenaufruf mitlädt, hier bringt Aufräumen spürbar etwas. Revisionen und Transients zu löschen macht die Datenbank kleiner und Backups schneller, wirkt sich auf die Ladezeit aber meist geringer aus. Deshalb gilt: vorher und nachher messen, statt blind ein Plugin laufen zu lassen.
Was ist autoload in wp_options und warum ist es wichtig?
In der Tabelle wp_options hat jede Option ein autoload-Flag. Optionen, die als autoload gelten, lädt WordPress bei jedem Seitenaufruf in den Speicher, unabhängig davon, ob die Seite sie braucht. Verlassene Plugins hinterlassen hier oft große Datenmengen, die dann bei jedem Request mitgeschleppt werden. Diese Leichen zu finden ist der größte Datenbank-Hebel.
Wie groß darf die autoload-Größe in wp_options sein?
Die Site-Health-Prüfung von WordPress (seit 6.6) meldet einen kritischen Status, sobald die autoload-Optionen zusammen über 800.000 Bytes liegen. Das ist eine Warnschwelle, kein Zielwert: Je weniger, desto besser. Entscheidend ist, welche Einträge die größten sind und ob sie bei jedem Aufruf wirklich gebraucht werden.
Sind abgelaufene Transients ein Problem für die Datenbank?
Abgelaufene Transients sind Ballast in wp_options, den WordPress nur gelegentlich selbst entfernt. Du kannst sie gefahrlos löschen, zum Beispiel mit wp transient delete --expired. Läuft ein persistenter Objekt-Cache wie Redis, liegen Transients dort statt in der Datenbank, und die Tabelle bleibt davon unberührt.
Hilft OPTIMIZE TABLE bei WordPress mit InnoDB?
Bei InnoDB wird OPTIMIZE TABLE auf ALTER TABLE ... FORCE abgebildet: Die Tabelle wird neu aufgebaut, Index-Statistiken werden aktualisiert und ungenutzter Platz im Clustered Index wird frei. Das lohnt sich nach großen Löschaktionen, ersetzt aber nicht das eigentliche Aufräumen. Gesperrt wird nur kurz, trotzdem läuft es besser außerhalb der Stoßzeiten.
Welches Plugin eignet sich zum Datenbank-Aufräumen?
Etablierte Optimierungs-Plugins wie WP-Optimize oder Advanced Database Cleaner erledigen Revisionen, Transients und Spam sicher und bieten vorher ein Backup an. Für das gezielte Aufräumen von autoload-Leichen ist ein direkter Blick per SQL oder WP-CLI präziser. In beiden Fällen gilt: erst Backup, dann aufräumen.
Wie oft sollte ich die WordPress-Datenbank aufräumen?
Für die meisten Seiten reicht ein bis zwei Mal im Jahr, plus einmalig nach dem Entfernen größerer Plugins, weil die ihre Optionen oft zurücklassen. Bei sehr aktiven Seiten mit vielen Beiträgen und Plugins kann ein Quartalsrhythmus sinnvoll sein. Wichtiger als die Frequenz ist, Revisionen dauerhaft zu begrenzen.
Passende Leistungen
Gründer & Full-Stack-Entwickler
20+ Jahre Erfahrung in der Webentwicklung. Spezialisiert auf Laravel, WordPress und individuelle Software für den Mittelstand.