Waarom je WordPress-database langzaam vol loopt en wat je eraan doet

Deze week kreeg ik een berichtje van een klant: “De site is trager geworden maar we hebben niks gewijzigd.” Dat is de meest voorkomende zin in mijn inbox. Niks gewijzigd. Behalve dat WordPress de afgelopen zes maanden gewoon zijn gang is gegaan, en dat is precies het probleem.

De database groeit stiller dan je denkt. Revisies, transient-opties, spam, wachtrijen — het stapelt zich op. En niemand kijkt ernaar, want het werkt. Tot het niet meer werkt.

Wat er precies in die database zit

Een WordPress-database bestaat uit een vaste set tabellen. De bekendste zijn wp_posts, wp_postmeta, wp_options en wp_comments. Maar er zijn er meer, en sommige groeien sneller dan je verwacht.

De wp_options tabel is een veelvoorkomende boosdoener. Elke plugin die iets wil onthouden, schrijft daar een rij in. Sommige plugins ruimen die rij nooit op. Na een paar jaar heb je honderden rijen van plugins die je allang verwijderd hebt. WordPress doorzoekt die tabel bij elke paginaopbouw. Des te groter de tabel, des te langer dat duurt.

Dan heb je wp_postmeta. Voor elk bericht of elke pagina kunnen plugins hier metadata opslaan. Denk aan SEO-velden, afbeeldingsgegevens, aangepaste velden. Als je duizenden producten of berichten hebt, loopt dit snel op tot miljoenen rijen.

Het revisiesysteem: handig, maar niet onbeperkt

WordPress slaat standaard elke versie van een bericht op. Typ je tien keer op ‘Opslaan’, dan staan er tien revisies in de database. Dat klinkt beheersbaar, maar bij een site die al jaren draait met actieve redacteuren, praat je al snel over tienduizenden revisies.

Die revisies staan in wp_posts met het type revision. Ze nemen ruimte in, maar ze vertragen ook queries omdat WordPress bij het ophalen van berichten door meer rijen moet. Je kunt het aantal revisies beperken via wp-config.php:

define('WP_POST_REVISIONS', 5);

Dit zorgt ervoor dat WordPress maximaal vijf revisies per bericht bewaart. Oudere worden automatisch verwijderd. Stel je dit in op een bestaande site, dan ruimt WordPress de overschot niet meteen op — dat doe je handmatig of met een opschoontool.

Transients: tijdelijke data die eeuwig blijft

Transients zijn bedoeld als tijdelijke cache-opslag in de database. Een plugin berekent iets zwaar, slaat het resultaat op als transient met een verloopdatum, en haalt het de volgende keer snel op. Goed idee in theorie.

In de praktijk verlopen transients wel, maar WordPress verwijdert ze niet automatisch. Ze blijven in wp_options staan met een vlag dat ze verlopen zijn. Bij een drukke site kunnen dat duizenden verlopen transients zijn. Ze doen niks meer, maar ze nemen ruimte in en vertragen de query die door wp_options zoekt.

Je kunt verlopen transients opruimen met een directe SQL-query. Wees voorzichtig: voer dit alleen uit als je een recente back-up hebt. En controleer daarna of alles nog werkt, want sommige plugins verwachten hun transients te vinden.

Spam en prullenbak: de stille opvullers

Reacties die als spam zijn gemarkeerd, blijven in de database staan totdat je ze handmatig verwijdert of de prullenbak leegt. Hetzelfde geldt voor berichten en pagina’s die je naar de prullenbak hebt gesleept. WordPress bewaart ze dertig dagen, daarna worden ze automatisch verwijderd — maar alleen als de cronjob draait.

Op veel gedeelde hostingomgevingen draait de WordPress-cronjob niet betrouwbaar. Dat betekent dat de prullenbak nooit automatisch leegloopt. Na een jaar heb je honderden verwijderde berichten en duizenden spamreacties die gewoon in de database zitten.

Controleer dit eens. Ga naar Reacties en filter op spam. Ga naar Berichten en kijk in de prullenbak. Als je daar dingen ziet die al maanden oud zijn, weet je genoeg. Leeg ze handmatig en stel daarna in of de cronjob betrouwbaar werkt — of vervang hem door een externe cron via je hostingpaneel.

Tabeloptimalisatie: wat het doet en wanneer het helpt

Als je rijen verwijdert uit een MySQL-tabel, geeft MySQL die schijfruimte niet meteen terug. De tabel heeft lege plekken, en MySQL moet daar omheen werken bij queries. Dit heet fragmentatie. Bij tabellen die veel schrijf- en verwijderbewerkingen meemaken, zoals wp_options en wp_comments, kan dit oplopen.

Je kunt tabellen optimaliseren via phpMyAdmin of via een SQL-commando. Dit herorganiseert de tabel, vult de gaten op en maakt de schijfruimte vrij. Op InnoDB-tabellen (de standaard in moderne MySQL-versies) is het effect op schijfruimte beperkter dan op MyISAM, maar het helpt wel bij het opruimen van de interne structuur.

Doe dit niet op een drukke productieserver tijdens piekuren. De operatie vergrendelt de tabel tijdelijk. Op kleine tot middelgrote sites valt dat mee, maar op grotere databases kan het een paar minuten duren.

Hoe je de database structureel schoon houdt

Eenmalig opruimen helpt, maar de database loopt daarna gewoon weer vol. Je hebt een structurele aanpak nodig. Dat betekent drie dingen: limieten instellen, periodiek opruimen en weten wat je plugins doen.

Limieten instellen

  • Beperk revisies via wp-config.php zoals hierboven beschreven
  • Schakel reacties uit als je ze toch niet gebruikt
  • Verwijder plugins die je niet meer nodig hebt, inclusief hun data

Periodiek opruimen

  • Plan maandelijks of per kwartaal een databasecheck in
  • Gebruik een beheertool die database-opruiming ondersteunt, maar controleer altijd wat die tool precies doet voor je op ‘uitvoeren’ klikt
  • Maak altijd een back-up voor je iets opruimt

Weten wat je plugins doen

  • Sommige plugins schrijven bij elke paginaopbouw naar de database. Dat is zelden nodig en vrijwel altijd een teken van slechte code.
  • Kijk in wp_options naar rijen met autoload = yes. Die worden bij elke paginaopbouw ingeladen, ongeacht of ze nodig zijn. Een grote hoeveelheid autoload-data is een directe aanslag op je laadtijd.

Als dat getal boven de één à twee megabyte uitkomt, is er werk aan de winkel. Zoek uit welke rijen het grootste zijn en of de bijbehorende plugin ze echt nodig heeft.

Wat je niet moet doen

Er zijn tools die beloven je database in één klik te optimaliseren. Sommige werken redelijk. Andere verwijderen dingen die je niet wilt verwijderen, of ze draaien queries op een manier die je database tijdelijk onbereikbaar maakt.

Vertrouw geen tool die je niet begrijpt. Als je niet weet wat een tool precies doet, voer hem dan niet uit op een productiesite zonder back-up. Dit klinkt als een open deur, maar ik zie het regelmatig misgaan. Een klant heeft een plugin geïnstalleerd, op ‘optimize’ geklikt, en daarna miste een complete custom post type zijn metadata. Geen back-up. Twee dagen werk om het te reconstrueren.

Verder: verwijder nooit handmatig rijen uit wp_postmeta of wp_options zonder te weten wat ze zijn. Sommige rijen zien er zinloos uit maar zijn essentieel voor een plugin of thema. De database heeft geen prullenbak. Wat weg is, is weg.

En tot slot: een grotere database is niet per definitie een probleem. Een webshop met tienduizend producten heeft een grote database, en dat hoort zo. Het gaat erom dat de database geen rommel bevat die er niet in hoort. Revisies van vijf jaar geleden, verlopen transients, spam, verwijderde berichten — dat hoort er niet in.

De klant die me die berichtje stuurde, had een wp_options tabel van bijna acht megabyte aan autoload-data. Drie plugins die hij jaren geleden had geïnstalleerd en daarna verwijderd, hadden elk honderden rijen achtergelaten. Na het opruimen en optimaliseren was de Time to First Byte meetbaar lager. Niks gewijzigd, inderdaad — maar de database had intussen wel zijn gang gegaan.

Kijk er eens in. Je zult verrast zijn wat je vindt.


Posted

in

by

Tags: