Waarom je WordPress-database langzaam vet wordt en wat je eraan doet

Een klant belde me op omdat zijn site “gewoon trager was geworden”. Geen nieuwe plugins, geen serverwijziging, niets veranderd. Gewoon trager. Na tien minuten kijken zag ik het: de database telde meer dan 80.000 rijen in de post_revisions-tabel en de options-tabel was opgeblazen tot een formaat dat nergens op sloeg. De site was vier jaar oud en nooit opgeruimd. Dat is de database-variant van een kantoor waar nooit iemand een papier weggooit.

Dit is een probleem dat sluipend ontstaat. Je merkt het pas als het al lang te laat is voor een snelle fix. Maar als je begrijpt hoe het werkt, kun je het voorkomen of in ieder geval beheersbaar houden.

Hoe een WordPress-database vet wordt

WordPress slaat bijna alles op in een MySQL-database. Berichten, pagina’s, instellingen, gebruikersdata, formulierinzendingen, sessiesleutels, transients, revisies. Elke keer dat je een pagina opslaat, maakt WordPress een revisie aan. Elke keer dat een plugin iets tijdelijks wil bewaren, schrijft hij een transient naar de options-tabel. Elke keer dat iemand een formulier invult en de plugin dat lokaal opslaat, groeit de database.

Het probleem is niet dat dit gebeurt. Het probleem is dat er standaard nauwelijks iets wordt opgeruimd. Revisies blijven staan. Transients verlopen wel, maar worden pas verwijderd als iemand ze opvraagt. Verwijderde berichten staan in de prullenbak tot je die handmatig leegt. Spam-reacties stapelen zich op. Formulierinzendingen uit drie jaar geleden zitten er nog gewoon in.

Na een paar jaar heb je een database die drie of vier keer zo groot is als nodig. Dat heeft directe gevolgen voor laadtijd, voor back-upgrootte, en voor hoe lang bepaalde queries duren.

De drie grootste boosdoeners

Als ik een opgeblazen database openmaak, zijn het bijna altijd dezelfde drie tabellen die het probleem veroorzaken.

Post revisions zijn de meest bekende dader. WordPress slaat standaard onbeperkt revisies op van elk bericht en elke pagina. Een redacteur die twintig keer op “opslaan” klikt voordat een artikel klaar is, genereert twintig revisies. Maal honderd artikelen, maal drie jaar, en je zit snel op tienduizenden rijen die je nooit meer nodig hebt.

De options-tabel is de tweede. Plugins schrijven hier instellingen naar, maar ook tijdelijke data als transients. Een transient is bedoeld als cache: een waarde die een plugin tijdelijk opslaat om een zware berekening of API-aanroep niet telkens te herhalen. Maar als een plugin slecht is geschreven, of als transients niet netjes worden opgeruimd na het verwijderen van een plugin, blijft die data gewoon staan. Ik heb options-tabellen gezien met meer dan 10.000 rijen, waarvan 90 procent verlopen transients van plugins die al maanden niet meer actief waren.

Formulierinzendingen en log-tabellen zijn de derde. Contactformulier-plugins slaan inzendingen lokaal op als fallback. Handig, maar als je dat nooit opruimt en de site al vijf jaar draait, heb je duizenden inzendingen staan. Hetzelfde geldt voor plugins die foutlogs of activiteitslogs bijhouden in de database. Die groeien onbeperkt als je er geen limiet op instelt.

Wat het concreet doet met je laadtijd

Een grote database is op zichzelf niet altijd een probleem. Het wordt een probleem als queries traag worden. En dat gebeurt om twee redenen.

De eerste reden is tabelgrootte. Hoe meer rijen een tabel heeft, hoe langer een zoekopdracht duurt als die niet op een geïndexeerde kolom zoekt. WordPress-queries zijn niet altijd optimaal geïndexeerd. Een query die door 80.000 revisies moet zoeken om de tien meest recente berichten te vinden, duurt langer dan dezelfde query op een tabel met 2.000 rijen.

De tweede reden is tabel-fragmentatie. MySQL slaat data op in blokken. Als je veel rijen verwijdert en nieuwe toevoegt, raken die blokken gefragmenteerd. De database moet dan meer schijfoperaties doen voor dezelfde query. Je kunt dit oplossen met een OPTIMIZE TABLE-commando, maar dat heeft alleen zin als je eerst de onnodige data hebt verwijderd.

In de praktijk zie ik dit terug in de Time to First Byte. Die is bij opgeblazen databases structureel hoger, soms 200 tot 400 milliseconden hoger dan bij een opgeschoonde versie van dezelfde site. Dat is genoeg om merkbaar te zijn voor bezoekers en om te zakken in paginasnelheidsscores.

Hoe je het opruimt

Eerst een back-up. Altijd. Je gaat straks data permanent verwijderen, dus zorg dat je een recente back-up hebt die je hebt getest. Dit is geen optionele stap.

Dan het opruimen zelf. Je hebt hiervoor twee routes: via een plugin of via directe SQL-queries.

De plugin-route is toegankelijker. Er zijn tools die je database analyseren en per categorie laten zien hoeveel je kunt winnen: zoveel revisies, zoveel transients, zoveel spamreacties. Je selecteert wat je wilt verwijderen en de plugin doet het werk. Voordeel is dat het laagdrempelig is en dat je niet in de database hoeft te zitten. Nadeel is dat je afhankelijk bent van wat de plugin aanbiedt en dat sommige tools agressiever opruimen dan je wilt.

De SQL-route geeft je meer controle. Als je toegang hebt tot phpMyAdmin of een andere databasetool, kun je zelf queries uitvoeren. Een paar voorbeelden van wat je dan doet:

Verwijder alle post-revisies, verlopen transients en leeg de prullenbak. Na het verwijderen voer je per tabel een OPTIMIZE TABLE uit. Dat ruimt de fragmentatie op en geeft de schijfruimte terug.

Wees voorzichtig met de transient-query. Sommige plugins gebruiken transients actief als cache. Als je die weggooit terwijl de site draait, moet de plugin alles opnieuw opbouwen. Dat is geen ramp, maar doe het bij voorkeur buiten piekuren.

Voorkomen is makkelijker dan opruimen

Als je de database eenmaal hebt opgeschoond, wil je voorkomen dat je over twee jaar weer op hetzelfde punt staat. Dat doe je door een paar instellingen aan te passen en een onderhoudsroutine in te voeren.

Het meest effectieve wat je kunt doen is het aantal revisies beperken. Dat regel je met één regel in je wp-config.php. Dit beperkt het aantal revisies per bericht tot vijf. Meer heb je in de praktijk zelden nodig. Als je revisies helemaal wilt uitzetten, gebruik je de waarde false, maar dat raad ik af. Revisies zijn nuttig als een redacteur per ongeluk iets overschrijft.

Stel ook een vaste prullenbakperiode in. Standaard bewaart WordPress verwijderde items dertig dagen. Voor de meeste sites is zeven dagen ruim voldoende.

Voor plugins die inzendingen of logs opslaan: zoek in de instellingen van die plugin naar een optie om de bewaartermijn te beperken. De meeste serieuze formulier-plugins hebben dit. Stel het in op dertig of zestig dagen. Meer heb je voor operationele doeleinden zelden nodig; als je inzendingen langer wilt bewaren, exporteer ze dan naar een spreadsheet of je CRM.

Plan ten slotte een vaste onderhoudsmoment in. Eén keer per kwartaal de database doorlichten, onnodige data verwijderen en tabellen optimaliseren. Dat kost je een halfuur en houdt de boel beheersbaar. Combineer het met je andere onderhoudstaken: updates controleren, back-ups testen, performance meten. Het is geen sexy werk, maar het is precies het werk dat voorkomt dat een klant je belt omdat zijn site “gewoon trager is geworden”.

Wanneer opruimen niet genoeg is

Soms is de database niet de enige oorzaak. Als je na een grondige opschoning nog steeds trage queries ziet, is het tijd om dieper te kijken.

Controleer of je slow query log aan staat op je server. Dat is een instelling in MySQL waarmee je queries kunt loggen die langer duren dan een ingestelde drempel, bijvoorbeeld één seconde. Wat je daarin vindt, vertelt je precies welke queries het probleem zijn. Soms is het een plugin die een ongeïndexeerde tabel gebruikt. Soms is het een widget of shortcode die bij elke paginaopbouw een zware databaseoperatie uitvoert.

Een object-cache kan in dat geval helpen. WordPress heeft een ingebouwde object-cache, maar die is standaard niet persistent: hij leeft alleen binnen één request. Als je een persistente object-cache installeert via Redis of Memcached, kunnen zware queries worden gecachet en hoeft WordPress ze niet bij elk bezoek opnieuw uit te voeren. Dit is een serverinstelling; je hebt er toegang voor nodig tot de serverconfiguratie.

Als je op gedeelde hosting zit en geen toegang hebt tot die instellingen, is dit het moment om te evalueren of die hosting nog past bij wat je site nodig heeft. Een opgeblazen database op een trage server is een combinatie die je niet met plugins oplost. Dan is migreren naar een betere omgeving de eerlijkste oplossing.

Maar begin altijd met het simpele werk. Opruimen, beperken, routinematig onderhouden. De meeste sites die ik zie hebben geen infrastructuurprobleem. Ze hebben gewoon vier jaar lang niemand gehad die de database heeft bijgehouden.


Posted

in

by

Tags: