Slow queries are one of the most common WordPress performance issues. Before you add an index or rewrite a query, you need to know why it’s slow. EXPLAIN is MySQL’s built-in query analyser — it shows you exactly how MySQL plans to execute a query and whether it’s using indexes or doing a full table scan.
Problem: How do you find out why a MySQL query is slow and which index — if any — it is actually using?
Solution: Run EXPLAIN before your SELECT statement — it returns the execution plan, including the scan type, the rows examined, and the key used, pointing you directly to the bottleneck.
Run EXPLAIN before any SELECT statement:
EXPLAIN
SELECT p.ID, p.post_title
FROM wp_posts p
JOIN wp_postmeta pm ON pm.post_id = p.ID
WHERE p.post_type = 'post'
AND p.post_status = 'publish'
AND pm.meta_key = '_featured'
AND pm.meta_value = '1';
The most important columns in the output:
type — the join type. Best to worst: system → const → eq_ref → ref → range → index → ALL. If you see ALL, a full table scan is happening.
key — the index MySQL chose to use. NULL means no index was used.
rows — estimated number of rows MySQL will examine. High numbers indicate a slow query.
Adding an index to wp_postmeta for a common meta key lookup:
-- Check existing indexes first
SHOW INDEX FROM wp_postmeta;
-- Add a composite index if meta_key + meta_value queries are slow
ALTER TABLE wp_postmeta
ADD INDEX idx_meta_key_value (meta_key, meta_value(20));
Enable the slow query log to catch queries that take over one second:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/tmp/mysql-slow.log';
NOTE: Adding indexes speeds up reads but slows down writes, as MySQL must update the index on every INSERT, UPDATE, and DELETE. Index only the columns you actually query on. On large meta_value columns, use a prefix length (e.g. meta_value(20)) rather than indexing the full column.