
Your WordPress site can have flawless image compression, a CDN, and a tuned cache plugin, and still feel sluggish the moment a logged-in user hits the admin or a cache miss forces a fresh page build. When that happens, the bottleneck is almost always the database. Every uncached request runs dozens to hundreds of SQL queries, and a neglected database makes each of them slower. This guide is about the part of WordPress speed that lives in MySQL, not the browser.
WordPress is query-heavy by design. A typical front-end page on a plugin-rich site fires anywhere from 30 to 200+ queries against MySQL or MariaDB before the first byte leaves the server. Caching plugins hide this by serving static HTML, but caches miss constantly: logged-in users, WooCommerce carts, search results, the entire wp-admin, REST API calls, and the first visitor after any cache purge all hit the database directly.
That is why database health shows up in Time To First Byte (TTFB) rather than the painting metrics most guides obsess over. Google's field data treats TTFB as a component of Largest Contentful Paint, and you want LCP under 2.5 seconds. A bloated database can quietly add 100–400ms of TTFB on uncached requests, and the WooCommerce and membership pages that can't be cached are exactly the ones where you can least afford it.
Not all bloat is equal. A database can be physically large yet fast, or compact yet slow. What matters is which tables get read on the hot path of a normal request.
On every single request, before WordPress does anything else, it runs one query: SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'. Everything that comes back is loaded into memory and kept for the whole request. This is the single most important thing to fix, because it is paid on 100% of requests, cached or not.
Plugins dump settings, license keys, and serialized blobs into autoloaded options and frequently forget to set autoload to no, or to delete them on uninstall. Healthy autoload size is under roughly 800KB–1MB. I have seen sites carrying 5MB+ of autoloaded data, much of it from plugins removed years ago. You can check yours instantly with this query in phpMyAdmin or wp-cli:
SELECT SUM(LENGTH(option_value)) AS autoload_bytes
FROM wp_options WHERE autoload = 'yes';
Or with WP-CLI: wp option list --autoload=on --format=count and wp db query "SELECT option_name, LENGTH(option_value) FROM wp_options WHERE autoload='yes' ORDER BY LENGTH(option_value) DESC LIMIT 20;" to find the worst offenders by name. Once you identify orphaned options, flip them off the autoload list rather than deleting blindly: wp option set _whatever value --autoload=no, or delete entries whose plugin is genuinely gone.
WordPress stores every revision of every post as its own row in wp_posts, with full content duplicated. A site with 300 posts and a dozen edits each can hold several thousand revision rows. These don't run on the front-end hot path, but they bloat wp_posts and slow down admin queries, exports, and search. Cap them in wp-config.php so the problem stops growing:
define( 'WP_POST_REVISIONS', 5 );
That keeps a usable undo history while preventing unbounded accumulation. Set it to false only if you genuinely never roll posts back.
Transients are WordPress's built-in short-lived cache, and they live in wp_options when no persistent object cache is present. Expired ones are not reliably garbage-collected, so they pile up. Worse, some plugins store transients as autoloaded, which loops you right back to the autoload problem. Clearing expired transients is safe and routine.
Spam comments in wp_comments, trashed posts, and orphaned rows in wp_postmeta and wp_commentmeta (metadata whose parent was deleted) round out the list. wp_postmeta is often the largest table on WooCommerce and ACF-heavy sites, and orphaned meta drags on the joins those plugins run constantly.
Cleanup shrinks the database. Indexing makes the queries that remain fast, and it's the step almost every "clean your database" article skips.
First, confirm your tables use the InnoDB storage engine, not the legacy MyISAM. InnoDB gives you row-level locking and far better concurrency under load. Run SHOW TABLE STATUS; and convert any stragglers with ALTER TABLE wp_posts ENGINE=InnoDB;. Most modern hosts default to InnoDB, but sites migrated from old servers often carry MyISAM tables.
Second, the big win on metadata-heavy sites: wp_postmeta ships with an index on meta_key but its meta_value column is unindexed by default. WooCommerce, lookups by SKU, and "meta_query" calls scan it. The widely recommended composite index helps enormously:
ALTER TABLE wp_postmeta ADD INDEX meta_key_value (meta_key(191), meta_value(100));
Test this on a staging copy first and measure with Query Monitor — on some workloads the default meta_key index is sufficient and the extra index only adds write overhead. The point is to add indexes based on the slow queries your site actually runs, not as a blanket ritual.
Don't optimize blind. Install Query Monitor (free) and load a few real pages while logged in. It surfaces total query time, the slowest individual queries, duplicate queries, and which plugin or theme fired them. This is how you discover that one poorly written plugin running a 400ms uncached query on every page — the kind of finding no automated cleanup tool will ever give you. Query Monitor also reports autoload size directly in its panel.
For routine cleanup, WP-Optimize (free) is the pragmatic default. Schedule a weekly job to clear expired transients, spam, trashed content, and revisions beyond your cap. Advanced Database Cleaner is the better tool for hunting orphaned options and identifying which plugin a given table or option belongs to. Both are housekeeping tools — they delete junk, but neither adds indexes, fixes a bad query, or converts storage engines. Don't expect a one-click plugin to solve a structural problem.
One operational note that matters more than people think: always optimize against a fresh backup, and run the bigger changes (index additions, engine conversions, bulk deletes) on a staging clone first. A botched bulk delete or an over-aggressive cleanup can break plugin functionality, and recovery is trivial with a backup and miserable without one.
If your site is busy enough that uncached database load is your real problem, the highest-impact move isn't deleting rows — it's a persistent object cache backed by Redis or Memcached. By default WordPress's object cache is per-request and thrown away when the page finishes. Redis makes it survive between requests, so the results of expensive queries (including all those autoloaded options and meta_query results) are served from memory instead of MySQL.
Most managed hosts — Kinsta, WP Engine, Cloudways, SiteGround — offer Redis as a toggle, and the Redis Object Cache plugin wires it up. On query-heavy and WooCommerce sites this routinely cuts TTFB more than any amount of row deletion, because it attacks query volume rather than table size.
wp-config.php, confirm InnoDB, and run Query Monitor on your three slowest page types.A clean, well-indexed, object-cached database won't show up in a Lighthouse screenshot the way a hero image will, but it's what keeps the cart page, the search results, and the logged-in dashboard fast — the moments where your real users actually decide whether your site feels quick or slow.
Site
Tools
We do not sell your email. We do not spam.
© 2026 RevealTheme. All rights reserved.