How to find the query slowing your site down
A slow site is usually a slow query wearing a disguise — here is how to catch it in the act.
A site that has grown slower over months rather than appearing broken all at once is very often a database problem, not a hosting problem: a query that ran fine against a small table is running the same way against a much larger one, taking longer every month as more rows get added. The fix usually is not "faster hosting" — it is finding the specific query and either adding an index or rewriting it.
Catch it while it is running
The most direct way to see what a database is spending its time on is to look at what is running right now, ideally while the slowness is actually happening. From the SQL tab in phpMyAdmin, or any connected client:
SHOW FULL PROCESSLIST;
This lists every current connection to the database, how long each has been running, and — critically, because of the word FULL — the complete query text rather than a truncated version. A query that has been sitting in the list for several seconds while everything else comes and goes quickly is your suspect. Note it down, because the list refreshes constantly and that row will not stay there for long.
Plain SHOW PROCESSLIST truncates the query text, which is rarely enough to identify which part of your application is actually responsible. Always use SHOW FULL PROCESSLIST when you are hunting for a specific culprit.
Understand why it is slow with EXPLAIN
Once you have the query text, put EXPLAIN in front of it and run it again:
EXPLAIN SELECT * FROM orders WHERE customer_email = 'someone@example.com';
This does not run the query for real — it asks MySQL to show its plan for running it, which is usually where the actual problem becomes visible. A few things in the output are worth checking specifically:
| What you see | What it means |
|---|---|
type: ALL | A full table scan — every row is being read to find matches. On a large table, this is usually the whole problem. |
key: NULL | No index is being used for this query at all, which is often why it fell back to a full scan. |
Extra: Using filesort | MySQL is sorting the results outside of an index, which gets slower as the result set grows. |
Extra: Using temporary | A temporary table was needed to complete the query — common with certain GROUP BY and DISTINCT queries lacking a supporting index. |
Seeing a full table scan on a query that filters by a specific column — customer_email in the example above — usually means that column has no index. Adding one is often the entire fix:
ALTER TABLE orders ADD INDEX idx_customer_email (customer_email);
As a rule of thumb, a column that regularly appears in a WHERE clause, a JOIN condition, or an ORDER BY on a large table is a reasonable candidate for an index. Do not index everything reflexively, though — every index speeds up reads but adds a small cost to every write, so index the columns you actually query by, not the whole table.
For a WordPress site specifically
A query-profiling plugin installed temporarily on the site itself will show you exactly which plugin, theme, or piece of code triggered each database query on a given page load, and how long it took — which is often faster than reasoning about it from the database side alone, especially if you do not control the application code directly. Remove or deactivate any profiling plugin once you have what you need; it adds overhead of its own and is not meant to run permanently on a live site.
Slow because of volume, not because of one bad query
Sometimes nothing is technically wrong with any single query — there are simply a lot of them, all reasonably fast individually, adding up under load. That is a different problem with a different fix: caching to avoid repeating the same query unnecessarily, and reducing how often the database is hit in the first place rather than optimising any one statement. Reducing database load covers that side of it.
Checking your table's overall health
A query that used to be fast and has slowly become slow can also be a sign that a table's indexes have grown fragmented or its statistics are stale, rather than the query itself being wrong. Running ANALYZE TABLE refreshes the statistics MySQL uses to decide how to run a query, and optimising a MySQL database covers this alongside the related OPTIMIZE TABLE command in more detail.
If you have identified the query and are not sure what index or rewrite would fix it, contact us with the query and the EXPLAIN output and we can advise on the best way forward for your specific case.
Related reading
OPTIMIZE TABLE reclaims space and refreshes statistics — but it behaves differently depending on the storage engine underneath.
How to reduce database load on a busy siteHow to find what is actually straining the database, and the maintenance most busy sites are quietly overdue for.
How to fix a "too many connections" errorThe database has a limit on simultaneous connections, and something is holding on to more of them than it should.
How to repair a corrupted MySQL tableA corrupted table has a specific fix, and it is different depending on whether the table is MyISAM or InnoDB.