WooCommerce database-optimalisatie voor shops met veel bestellingen

Een WooCommerce-shop met tienduizenden bestellingen bouwt specifieke databaseproblemen op die generiek WordPress-advies niet oplost. Het admin-orderscherm kruipt, de rapportagepagina valt stil, en de database blijft maar groeien. Dit artikel loopt door de concrete stappen om te achterhalen welk deel van de database de flessenhals is, te migreren naar HPOS als dat nog niet is gebeurd, de tabellen op te schonen die stilletjes meegroeien naast de orders, en onderhoud in te richten dat voorkomt dat het probleem terugkomt.

Inhoud

Wat je nodig hebt

  • Een WooCommerce-shop op WooCommerce 8.2 of nieuwer (de versie die HPOS als stabiel en standaard markeerde voor nieuwe installaties). Oudere versies kun je gewoon eerst updaten.
  • SSH- of WP-CLI-toegang tot de server. De meeste stappen gebruiken wp-commando's. Heb je alleen wp-admin, dan dekt het scherm WooCommerce > Status > Gereedschap een deel van dezelfde acties, maar CLI is sneller en preciezer bij grote tabellen.
  • Een actuele databasebackup. Elke stap hieronder is omkeerbaar, maar een backup betekent dat je niet op dat woord hoeft te vertrouwen. Op managed hosting: check dat je dagelijkse backup minder dan 24 uur oud is. Op een eigen server: wp db export backup-$(date +%Y%m%d).sql.
  • Toegang tot phpMyAdmin, Adminer of directe MySQL/MariaDB CLI voor diagnostische queries.
  • Kennis van waarom WooCommerce andere druk op de database legt dan een contentsite. Dat concept-artikel behandelt het "waarom"; dit artikel behandelt het "hoe".

De trage queries vinden

Voordat je iets verandert: achterhalen wat eigenlijk traag is. De verkeerde fix voor de verkeerde bottleneck kost je alleen maar tijd.

Stap 1. Installeer Query Monitor op een staging-kopie (nooit productie voor debugging). Open het admin-orderscherm. Sorteer in het Query Monitor-paneel queries op duur. De top drie queries vertellen je of de kosten in wp_postmeta-joins zitten (legacy order storage), in wp_wc_orders-lookups (HPOS), of ergens heel anders.

Stap 2. Check welke orderopslag actief is. Ga in wp-admin naar WooCommerce > Instellingen > Geavanceerd > Functies. Staat er "WordPress posts storage" bij "Order data storage", dan draait de shop op legacy en is HPOS-migratie de grootste enkelvoudige verbetering. Staat er "High-Performance Order Storage", dan is HPOS al actief en zit de bottleneck ergens anders: verweesde data, Action Scheduler-bloat of autoload-druk in wp_options.

Stap 3. Meet de omvang van de tabellen die typisch opzwellen. Draai dit in je databaseclient:

SELECT
  table_name,
  ROUND(data_length / 1024 / 1024, 1) AS data_mb,
  ROUND(index_length / 1024 / 1024, 1) AS index_mb,
  table_rows
FROM information_schema.tables
WHERE table_schema = DATABASE()
  AND table_name IN (
    'wp_postmeta', 'wp_posts',
    'wp_wc_orders', 'wp_wc_orders_meta',
    'wp_actionscheduler_actions', 'wp_actionscheduler_logs',
    'wp_woocommerce_sessions', 'wp_options'
  )
ORDER BY data_length DESC;

Op een shop met 100.000+ bestellingen die nooit is opgeschoond kan wp_actionscheduler_logs alleen al tientallen gigabytes bereiken. Die tabel heeft niks met orderopslag te maken, maar alles met hoe traag de admin aanvoelt.

Migreren naar HPOS (High-Performance Order Storage)

Draait de shop nog op legacy post-based orderopslag, dan is dit veruit de grootste performancewinst die er te halen valt. WooCommerce's eigen benchmarks op een testshop met 400.000 orders laten het verschil zien:

Operatie Legacy (wp_posts) HPOS Verbetering
1.000 orders aanmaken 78,1 s 15,2 s ~5x sneller
10 checkouts 1,51 s 0,99 s ~1,5x sneller
Zoeken op metadata 0,639 s 0,053 s ~10x sneller
Filteren op klant-ID 0,599 s 0,016 s ~40x sneller

De reden is structureel. Legacy storage schrijft zo'n 40 rijen per order (een naar wp_posts, ~39 naar wp_postmeta). HPOS schrijft maximaal 5 rijen over vier eigen tabellen met indexen die precies passen bij de queries die WooCommerce draait.

De migratiestappen

Stap 1. Draai eerst de compatibiliteitscheck. Ga naar WooCommerce > Instellingen > Geavanceerd > Functies en bekijk de compatibiliteitsstatus. WooCommerce markeert extensies die nog geen HPOS-ondersteuning hebben gedeclareerd. Een incompatibele extensie blokkeert de migratie niet per se, maar het betekent wel dat je op staging moet testen voordat je productie aanraakt.

Stap 2. Schakel HPOS in met synchronisatie aan. Dit is het veilige pad: zowel de oude als de nieuwe tabellen blijven in sync, dus terugdraaien is een instellingswijziging, geen datarecovery.

wp wc hpos enable --with-sync

Of in wp-admin: zet "Order data storage" op High-Performance Order Storage en houd "Compatibiliteitsmodus inschakelen" aangevinkt. Vanaf dit moment schrijven nieuwe orders naar HPOS-tabellen en worden ze teruggesynchroniseerd naar wp_posts. Bestaande orders moeten nog gemigreerd worden.

Stap 3. Synchroniseer bestaande orders. Op een shop met minder dan 100.000 orders is de ingebouwde achtergrondsynchronisatie meestal binnen een paar uur klaar. Bij grotere shops is de CLI betrouwbaarder:

wp wc hpos sync --batch-size=500

WooCommerce's migratiegids voor grote shops beschrijft een shop met 9 miljoen orders waar de CLI-sync ongeveer een week duurde. Die gids raadt een drietrapsaanpak aan: houd sync-on-read actief voor de eerste ~6 uur, zet het dan uit, en zet na ~1 week ook sync-on-write uit zodra je de data-integriteit hebt bevestigd.

Stap 4. Verifieer de data-integriteit na afloop van de sync:

wp wc hpos verify_cot_data --verbose

Dit commando vergelijkt orders over beide backends en rapporteert elke mismatch. Nul mismatches betekent dat de migratie schoon is.

Stap 5. Zodra je zeker bent, schakel je de compatibiliteitsmodus uit om de overhead van dubbel schrijven te stoppen:

wp wc hpos compatibility-mode disable

Gaat er toch iets mis, dan is het officiële terugdraaipad expliciet: synchronisatie weer aanzetten, wachten tot de tabellen gelijk lopen, en dan terugswitchen naar posts storage. Beide richtingen zijn hot migrations zonder downtime.

Let op voor april 2026 en later: WooCommerce 10.7, gepland op 14 april 2026, schakelt sync-on-read standaard uit. Dit raakt shops die custom code hebben die orders rechtstreeks naar wp_postmeta schrijft (buiten de WooCommerce CRUD-laag om). Heb je maatwerk-integraties die wp_update_post() of update_post_meta() gebruiken voor orderdata, test ze dan voordat je naar 10.7 upgradet.

De tabellen opschonen die meegroeien naast orders

HPOS-migratie fixt het query-pad voor orders. Onderstaande stappen pakken de tabellen aan die op elke actieve WooCommerce-shop stilletjes opzwellen, ongeacht welke orderopslag actief is.

Action Scheduler-logs

De tabel wp_actionscheduler_logs registreert een log-entry voor elke scheduled action die WooCommerce en extensies draaien. De standaard retentie is 30 dagen, en de standaard opruimbatch is 20 rijen per keer. Op een shop die honderden orders per dag verwerkt, kan het opruimen het niet bijbenen en groeit de tabel ongebreideld. GitHub-issue #26818 documenteert shops waar deze tabel tot 55 GB+ groeide.

Ruim de achterstand op:

# Verwijder afgeronde acties ouder dan 7 dagen (pas de drempel aan naar wens)
wp action-scheduler clean --before="7 days ago" --status=complete

Verhoog daarna de opruimbatch zodat die voortaan bijblijft. Voeg dit toe aan functions.php van je thema of een site-specifieke plugin:

// Verhoog Action Scheduler cleanup van 20 naar 500 per batch
add_filter('action_scheduler_cleanup_batch_size', function () {
    return 500;
});

Verlopen WooCommerce-sessies

De tabel wp_woocommerce_sessions slaat winkelwagen-sessiedata op voor elke bezoeker die iets aan de cart toevoegt. Verlopen sessies van afgebroken bestellingen hopen zich op en worden niet op elke shop automatisch opgeruimd. Verwijder ze:

DELETE FROM wp_woocommerce_sessions
WHERE session_expiry < UNIX_TIMESTAMP();

Op een shop met veel verkeer kan dit honderden megabytes vrijmaken.

Verweesde postmeta

Als de shop jarenlang op legacy storage draaide voordat je migreerde naar HPOS, bevat wp_postmeta waarschijnlijk verweesde rijen: meta-entries waarvan de bovenliggende post niet meer bestaat, revisie-meta die nergens meer voor dient, en overgebleven data van verwijderde extensies. De veilige diagnostische query:

SELECT COUNT(*)
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL;

Is het aantal substantieel (duizenden of meer), verwijder de wezen dan:

DELETE pm
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL;

Autoload-data in wp_options

WooCommerce-extensies zijn een veelvoorkomende bron van autoload-bloat in wp_options. Sessiedata, grote productattribuut-arrays en extensie-instellingen stapelen zich op. Het autoload-artikel beschrijft de volledige diagnostiek en opruim-workflow. De korte versie: als je autoloaded data de 800 KB overschrijdt (de WordPress 6.6 Site Health-drempel), is dat onafhankelijk van orderopslag de moeite waard om aan te pakken.

Postrevisies

WordPress slaat revisies op voor elke bewaarde wijziging. Order-edits op legacy storage maakten ook postrevisies aan. Beperk ze in wp-config.php:

define('WP_POST_REVISIONS', 5);

Ruim bestaande overtollige revisies op:

wp post delete $(wp post list --post_type=revision --format=ids) --force

Het resultaat controleren

Draai na alle stappen de tabelgrootte-query uit de diagnostische stap opnieuw. Vergelijk de data_mb-waarden voor en na. Op een shop die op legacy storage draaide met 100.000+ bestellingen en nooit was opgeschoond, heb ik de totale databaseomvang 40 tot 60 procent zien krimpen.

Open daarna het admin-orderscherm. Filter, zoek, sorteer op datum. Op een shop die van legacy naar HPOS is gemigreerd is het verschil meestal meteen duidelijk: een scherm dat er 8 tot 12 seconden over deed, laadt in minder dan 2.

Terugkerend onderhoud inrichten

Het opruimen hierboven is geen eenmalige actie. Deze tabellen groeien gewoon terug.

  • Action Scheduler: het action_scheduler_cleanup_batch_size-filter uit de eerdere stap houdt de tabel onder controle. Check de tabelgrootte elk kwartaal.
  • Verlopen sessies: stel een gepland WP-CLI-commando of een servercron in die maandelijks de sessie-cleanup-SQL draait.
  • Autoload-audit: draai de vier-waarden autoload-meetquery elk kwartaal. Vijf minuten checken voorkomt maanden opgebouwde overhead.
  • Tabeloptimalisatie: draai wp db optimize maandelijks om schijfruimte terug te claimen van verwijderde rijen. InnoDB geeft ruimte niet automatisch terug aan het bestandssysteem na grote deletes.

Wanneer je hulp moet inschakelen

Als het admin-orderscherm na HPOS-migratie en een volledige opruimronde nog steeds traag is, liggen de overgebleven oorzaken doorgaans buiten wat je zelf kunt oplossen:

  • N+1-queries van extensies. Een extensie die per orderrij op het admin-lijstscherm een databasequery draait, levert een lineaire vertraging op die geen enkele opruimactie fixt. Query Monitor op staging laat de schuldige zien. De oplossing is meestal een pluginvervanging of een supportticket bij de extensie-ontwikkelaar.
  • InnoDB buffer pool te klein voor de working set. Heeft de databaseserver 1 GB RAM en zijn de gezamenlijke WooCommerce-tabellen 4 GB, dan leest MySQL constant van schijf. innodb_buffer_pool_size moet groot genoeg zijn om de working set vast te houden. Op managed hosting is dit een supportticket. Op een eigen server: zet het op 50 tot 70 procent van het beschikbare RAM. De MySQL 8.0 optimalisatiehandleiding behandelt de tuning.
  • Read replicas voor rapportages. Draait de shop zware WooCommerce Analytics-queries tegelijk met orderverwerking, dan concurreren die rapportqueries met checkout-queries om databaseresources. Rapportages naar een read replica offloaden scheidt de workloads volledig. Dit is een infrastructuurwijziging, geen WordPress-wijziging.

Wanneer je hulp inschakelt, heb dan dit paraat: de output van de tabelgrootte-query, de actieve orderopslag-backend (HPOS of legacy), je WooCommerce- en PHP-versies, of er een object cache actief is (Redis of Memcached), en de drie traagste queries uit Query Monitor op het betreffende scherm. Dat is genoeg om mee te triagen zonder een tweede ronde.

Klaar met terugkerende traagheid?

Traagheid komt vaak terug na snelle fixes. Professioneel onderhoud houdt updates, caching en limieten consequent op orde.

Bekijk WordPress onderhoud

Doorzoek deze site

Begin met typen om te zoeken, of blader door de kennisbank en blog.