MySQL’s slow query log captures every query that exceeds a configurable threshold, but reading thousands of raw log lines is impractical. Percona’s pt-query-digest aggregates them into a ranked report, showing the queries with the highest total execution time, call count, and worst-case duration.
Problem: The MySQL slow query log records individual slow queries, but on a busy WordPress server it accumulates thousands of entries — identifying the most impactful queries to optimise requires aggregating and analysing patterns across the log.
Solution: Use pt-query-digest from Percona Toolkit to parse the slow query log — it groups similar queries by fingerprint, ranks them by total execution time, and outputs the call count, average duration, and worst-case example for each. Run it with pt-query-digest /var/log/mysql/slow.log | head -200 to get an immediate priority list.
The examples below enable the slow query log, run pt-query-digest against it, interpret the output, and use EXPLAIN to fix the top offender in a WordPress database.
-- Enable the slow query log at runtime (no restart needed)
SET GLOBAL slow_query_log = ON;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL long_query_time = 0.5; -- log queries slower than 500ms
SET GLOBAL log_queries_not_using_indexes = ON; -- also log full-table-scans
-- Persist in my.cnf for survival across restarts:
-- [mysqld]
-- slow_query_log = 1
-- slow_query_log_file = /var/log/mysql/slow.log
-- long_query_time = 0.5
-- log_queries_not_using_indexes = 1
-- Rotate the log without restarting MySQL:
-- FLUSH SLOW LOGS;
-- Check current status:
SHOW VARIABLES LIKE 'slow_query%';
SHOW GLOBAL STATUS LIKE 'Slow_queries';
Run pt-query-digest and interpret the report:
# Install Percona Toolkit
sudo apt install percona-toolkit
# Analyse the slow log — generates a ranked summary
pt-query-digest /var/log/mysql/slow.log > /tmp/slow-report.txt
# Key fields in the report:
# Rank Query ID Response time Calls R/Call Apdex V/M Item
# 1 0xABC... 48.3261 42.5% 12345 0.0039 1.00 0.01 SELECT wp_postmeta...
# Filter to just the top 5 queries
pt-query-digest --limit=5 /var/log/mysql/slow.log
# Analyse a live running instance (requires PROCESS privilege)
pt-query-digest --processlist h=127.0.0.1,u=root
# The EXPLAIN for a typical WordPress slow query:
# "SELECT * FROM wp_postmeta WHERE meta_key = '_price' ORDER BY meta_value+0 LIMIT 20"
-- Fix the top offending query: missing composite index on wp_postmeta
EXPLAIN SELECT post_id, meta_value
FROM wp_postmeta
WHERE meta_key = '_price'
ORDER BY CAST(meta_value AS DECIMAL(10,2))
LIMIT 20;
-- type: ALL → full table scan — this is the problem
-- Add a composite index
ALTER TABLE wp_postmeta ADD INDEX idx_meta_key_value (meta_key, meta_value(20));
-- Re-run EXPLAIN to confirm it now uses the index
EXPLAIN SELECT post_id, meta_value
FROM wp_postmeta
WHERE meta_key = '_price'
ORDER BY CAST(meta_value AS DECIMAL(10,2))
LIMIT 20;
-- type: ref, key: idx_meta_key_value — index used
NOTE: Run pt-query-digest weekly in production and track the top-5 slow queries over time. A query that was fast last month but appears in the top-5 now usually signals that a table has grown past the point where its current index is effective.