A WordPress database grows in ways that have nothing to do with how much you have written. A site with two hundred posts can carry a database several times larger than its content, and the weight is almost entirely things WordPress kept in case you wanted them.
The result is a site that gets slower without anyone changing anything.
The single most important thing: autoloaded options
Start here, because it is the one that affects every page load.
The wp_options table has an autoload column. Every row marked yes is read from the database on every single request, before WordPress knows what page it is serving.
A healthy site has a few hundred kilobytes of autoloaded data. Plugins that store large blobs there, and plugins that leave their data behind after being deleted, push it into megabytes, and the site pays that cost on every request including the ones served to bots.
Check the total in phpMyAdmin:
SELECT ROUND(SUM(LENGTH(option_value))/1024/1024, 2) AS mb FROM wp_options WHERE autoload = 'yes';
Under 1 MB is fine. Over 3 MB is a real problem worth an hour of your time.
Then find what is responsible:
SELECT option_name, ROUND(LENGTH(option_value)/1024, 1) AS kb FROM wp_options WHERE autoload = 'yes' ORDER BY LENGTH(option_value) DESC LIMIT 20;
The names usually identify the plugin. Anything from a plugin you removed months ago can be deleted; anything from a plugin still in use should be set to autoload = 'no' rather than deleted, if it is not needed on every request.
Take a database export before touching any of it. Managing databases with phpMyAdmin deals with both the export and the SQL tab.
Post revisions
WordPress stores a complete copy of a post every time you save a draft. An article edited thirty times is thirty-one full copies in the database.
Limit it in wp-config.php:
define('WP_POST_REVISIONS', 5);
That keeps the safety net and stops the accumulation. Setting it to false disables revisions entirely, which saves more and removes your ability to recover an edit you regret: usually the wrong trade.
Existing revisions are not removed by that setting. Deleting them is a cleanup job, and it is one of the few places where a plugin genuinely earns its place.
What else accumulates
Trashed posts and comments, kept for 30 days by default. Empty them.
Spam comments that were caught and never deleted. On a site with an open comment form this can be tens of thousands of rows.
Expired transients, cached values with an expiry, which WordPress does not reliably clean up. They live in wp_options and often make up a surprising share of it.
Orphaned metadata belonging to posts that no longer exist.
Tables from deleted plugins. Most plugins do not remove their tables on uninstall, so a site that has tried several page builders carries all of them.
Removing tables from plugins you deleted
These are safe to delete only if you are certain the plugin is gone and not coming back.
Table names are usually prefixed with the plugin's name, which makes identification straightforward. What is not straightforward is telling a deleted plugin's table from an active one's, so check the plugin list before deleting anything.
Export first. This is irreversible and there is no confirmation step that will save you.
Optimizing tables
After deleting a lot of rows, the space is not returned to the filesystem automatically. The table has gaps where the data was.
phpMyAdmin offers Optimize Table, which rebuilds the table and reclaims the space. Run it after a cleanup rather than routinely, on an unchanged table it accomplishes nothing.
It locks the table while it runs. On a large table on a busy site, do it when traffic is low.
Cleanup plugins: useful, and not to be left installed
Several plugins do all of the above through an interface, and they are genuinely easier than writing SQL.
Two rules. Take a backup before running one. They delete in bulk and offer no undo. And remove the plugin afterwards: a tool that can drop tables is not something to leave active for the convenience of running it twice a year.
Be wary of the aggressive presets. "Clean everything" includes things some plugins rely on, and the breakage appears later without an obvious cause.
What this does and does not fix
Worth being honest about, because database cleanup is often prescribed for problems it cannot touch.
It does help when autoloaded options are bloated, when tables are large enough to slow queries, and when backups have become unwieldy because of accumulated junk.
It does not fix a slow site whose real problem is no caching, oversized images, or a plugin running expensive queries on every page. Those are far more common causes, and a tidy database does not make an uncached page fast. Optimizing WordPress performance explains the ones that matter more.
Check the autoload figure, fix it if it is high, clear the obvious accumulation, and then move on to caching. That is the order that produces results.
Keeping it from coming back
Set the revision limit once and it applies forever.
Delete plugins you stopped using rather than deactivating them: a deactivated plugin's data stays and its files remain on disk to be exploited.
And check the autoload total every few months. It creeps up quietly, and it is the number that tells you whether the database is a problem at all.
A store's database grows in ways a normal site's does not, and the disposable rows sit beside ones that must never be deleted. For the difference, see WooCommerce Database Growth: What Fills It.
The other half of a site that has grown is the uploads directory, which nothing cleans automatically. How to Manage a Large WordPress Media Library picks it up from there.