MySQL slow query log lezen en fixen

Leer hoe je de MySQL slow query log activeert, analyseert en gebruikt om trage queries in WordPress op te sporen en te fixen.

26 april 20267 min leestijdDoor We Develop Communication

Een trage WordPress-site begint vaak onder de motorkap, bij de database. En als je echt wilt weten waar je seconden verliest, moet je de MySQL slow query log leren lezen en fixen. Dit logbestand vertelt je precies welke queries je site afremmen, hoe vaak ze draaien en hoe lang ze duren.

In dit artikel leer je hoe je de slow query log activeert, welke tools je gebruikt om de log te analyseren en hoe je de gevonden queries daadwerkelijk oplost. Zonder dit logbestand gok je; mét dit logbestand meet je.

Wat is de slow query log precies?

De slow query log is een ingebouwde MySQL-functionaliteit die elke query vastlegt die langer duurt dan een door jou ingestelde drempel. Ook queries die zonder index draaien kun je optioneel laten loggen.

Voor WordPress-sites is dit goud waard. De meeste performance-problemen komen voort uit queries in wp_options, wp_postmeta of uit plugins die ongelimiteerde LIKE '%...%' zoekopdrachten uitvoeren.

Als je eerst een breder beeld wilt van waar je bottleneck zit, lees dan WordPress performance bottlenecks herkennen. Voor database-tuning in bredere zin is database optimalisatie voor WordPress een goed vertrekpunt.

De slow query log activeren

Je activeert de log via je MySQL-configuratiebestand (my.cnf op Linux of my.ini op Windows). Voeg de volgende regels toe onder [mysqld]:

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1

Herstart MySQL daarna met sudo systemctl restart mysql. Controleer vervolgens of de log actief is:

SHOW VARIABLES LIKE 'slow_query_log%';
SHOW VARIABLES LIKE 'long_query_time';

Zonder herstart activeren

Wil je niet herstarten? Dat kan ook via runtime-variabelen. Handig op productieservers waar je downtime wilt vermijden.

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

Let op: deze instellingen verdwijnen bij een herstart. Zet ze dus ook in je configuratiebestand als je ze permanent wilt.

Welke long_query_time kies je?

De standaardwaarde is 10 seconden, veel te hoog voor een serieuze WordPress-site. Gebruik deze richtlijnen:

  • 1.0 seconde, goede startwaarde voor de meeste sites
  • 0.5 seconde, als je al hebt geoptimaliseerd en fijnmazig wilt tunen
  • 0.1 seconde, alleen tijdens gerichte debugsessies, anders wordt de log te groot

Hoe lager je drempel, hoe meer data je log verzamelt. Dat kost schijfruimte en I/O. Monitor dus je diskusage.

De log lezen met mysqldumpslow

MySQL komt met de ingebouwde tool mysqldumpslow. Hiermee groepeer je vergelijkbare queries en krijg je een overzicht van de grootste zondaars.

mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

De flags betekenen:

  • -s t, sorteer op totale tijd (t), aantal keer uitgevoerd (c), of gemiddelde tijd (at)
  • -t 10, toon alleen de top 10

De tool abstraheert concrete waarden (WHERE id = 5 wordt WHERE id = N), waardoor je vergelijkbare queries in één groep ziet.

De log lezen met pt-query-digest

Voor serieus werk gebruik je pt-query-digest uit de Percona Toolkit. Die geeft aanzienlijk rijkere analyses dan mysqldumpslow.

pt-query-digest /var/log/mysql/slow.log > report.txt

In het rapport zie je per query:

  • Totale tijd en percentage van alle tijd
  • Aantal aanroepen
  • Minimum, maximum, gemiddelde en 95e percentiel duur
  • Voorbeeld-queries met concrete waarden
  • Welke tabellen betrokken zijn

Dat 95e percentiel is cruciaal. Een query die gemiddeld 200 ms duurt maar in zijn top 5% 4 seconden neemt, is waarschijnlijk je echte probleem.

Trage queries interpreteren

Stel, pt-query-digest wijst deze query aan als grootste zondaar:

SELECT * FROM wp_postmeta 
WHERE meta_key = '_some_plugin_cache' 
AND meta_value LIKE '%user_123%';

Dit is een klassiek WordPress-probleem. Een LIKE '%...%' kan geen index gebruiken en scant de hele tabel. Op een site met 500.000 postmeta-rijen is dat dramatisch.

EXPLAIN gebruiken

Voer EXPLAIN uit op elke verdachte query om te zien wat MySQL doet:

EXPLAIN SELECT * FROM wp_postmeta 
WHERE meta_key = '_some_plugin_cache' 
AND meta_value LIKE '%user_123%';

Let op de kolommen type, possible_keys, key en rows. Zie je type: ALL? Dan scant MySQL de volledige tabel. Zie je rows: 500000? Dan weet je ook hoeveel werk dat is.

Trage queries fixen

Nu het echte werk. Hoe je een query oplost hangt af van de oorzaak.

1. Ontbrekende indexes toevoegen

Als je query filtert op een kolom zonder index, voeg die dan toe:

ALTER TABLE wp_postmeta 
ADD INDEX idx_meta_key_value (meta_key(20), meta_value(50));

Gebruik prefix-indexes voor lange tekstkolommen om de index klein te houden. Test wel altijd eerst op staging, verkeerde indexes kunnen INSERT- en UPDATE-queries juist vertragen.

2. LIKE-queries herschrijven

Een LIKE '%term%' is fundamenteel traag. Overweeg alternatieven:

  • FULLTEXT index voor echte zoekfunctionaliteit
  • Een aparte lookup-tabel met gestructureerde data
  • Externe zoekindex zoals Elasticsearch of Meilisearch
  • Object caching zodat de query minder vaak draait, zie object caching met Redis in WordPress

3. Autoloaded options opschonen

Veel trage queries komen uit wp_options met autoload = yes. Lees autoloaded options: stille performance killer voor een concreet stappenplan.

4. WP_Query verbeteren

Als de trage query uit een WP_Query komt, is het vaak de meta_query of tax_query. Zie hoe werkt WP_Query onder de motorkap? voor concrete optimalisaties.

5. Plugin identificeren

Soms weet je niet welke plugin de query veroorzaakt. Gebruik Query Monitor in combinatie met de slow query log. Query Monitor toont je de call stack van elke query binnen een request, zodat je de exacte plugin of functie vindt.

Voor een gestructureerde aanpak van plugin-debugging lees je debugging van trage plugins in WordPress.

De log roteren en beheren

Een actieve slow query log groeit snel. Zonder rotatie vul je je schijf en daarmee crasht je hele server.

Configureer logrotate met een file als /etc/logrotate.d/mysql-slow:

/var/log/mysql/slow.log {
    daily
    rotate 7
    missingok
    compress
    delaycompress
    notifempty
    postrotate
        mysql -e 'SELECT @@global.slow_query_log_file;' | tail -1
        mysqladmin flush-logs
    endscript
}

Zo houd je een week aan geschiedenis, gecomprimeerd, en dwing je MySQL om een nieuw logbestand te beginnen.

De log op productie gebruiken

Mag je dit op een drukke productieserver aanzetten? Ja, mits je:

  • Een redelijke long_query_time gebruikt (1 seconde of hoger)
  • log_queries_not_using_indexes uitzet op zeer drukke sites
  • De log op een aparte disk of partitie plaatst om I/O-impact te beperken
  • Automatische rotatie en monitoring inricht

De overhead van de slow query log zelf is minimaal, vaak onder 1%, maar het wegschrijven van veel data naar dezelfde disk als je database kan je database afremmen.

Werken met een managed database

Gebruik je een managed MySQL bij bijvoorbeeld AWS RDS, DigitalOcean of een Nederlandse hoster? Dan activeer je de slow query log vaak via het controlepaneel of via parameter groups. De log zelf download je als bestand of lees je via een ingebouwde viewer.

Check de documentatie van je provider. De meeste bieden ook een eigen UI voor slow query analyse, bijvoorbeeld RDS Performance Insights.

Van meting naar structuur

De slow query log is een diagnosemiddel, geen eindpunt. Als je structureel snellere queries wilt, combineer je hem met:

Het doel is niet één query fixen, maar een workflow opzetten waarbij je wekelijks of maandelijks de top 10 trage queries doorloopt.

Veelgestelde vragen

Wat is de MySQL slow query log?

De slow query log is een logbestand waarin MySQL alle queries bijhoudt die langer duren dan een bepaalde drempelwaarde. Je gebruikt het om traag presterende queries op te sporen en te optimaliseren.

Hoe activeer ik de slow query log?

Je activeert de log via my.cnf of my.ini door slow_query_log=1 in te stellen, een pad voor slow_query_log_file op te geven en long_query_time te configureren. Daarna herstart je MySQL. Runtime activeren kan met SET GLOBAL.

Welke long_query_time moet ik instellen voor WordPress?

Voor WordPress is 1 seconde een goed startpunt. Wil je ook subtiele trage queries opsporen, zet hem dan op 0.5 of zelfs 0.1 seconden. Houd rekening met extra schijfruimte en I/O.

Hoe analyseer ik een slow query log efficiënt?

Gebruik pt-query-digest of mysqldumpslow om de log te parsen. Deze tools groeperen vergelijkbare queries en tonen je welke queries het meeste tijd kosten, gesorteerd op totale impact in plaats van losse aanroepen.

Wat doe ik nadat ik een trage query heb gevonden?

Voer EXPLAIN uit op de query om te zien welke indexes ontbreken, voeg gerichte indexes toe, herschrijf inefficiënte joins of LIKE '%...%'-queries, en voeg caching toe op applicatieniveau waar het kan.

Veelgestelde vragen

Klaar om digitaal te groeien?

Wij helpen Nederlandse bedrijven met webtechnologie en SEO-strategieën die écht werken. Neem vrijblijvend contact op.