← Home

DB maintenance commands in PostgreSQL: Analyze, Reindex, Vacuum


Actively updated database tables in PostgreSQL sometimes require maintenance because of table and index bloat, obsolete and suboptimal query plans and sometimes corrupted indexes. Bloated tables and indexes occupy too much of disk space and memory, suboptimal queries and corrupted indexes slow down database queries. As a result, database performance may significantly degrade. PostgreSQL has a few commands to help developers solve those problems: ANALYZE, VACUUM, REINDEX.


ANALYZE collects statistics about the contents of all or several columns in a table or entire database. These statistics are then used by the query planner to produce efficient execution plans for queries.


Please note, that ANALYZE doesn't read or update indexes. It deals only with table/column contents. ANALYZE. Other queries may read from the table while ANALYZE is running.

Use ANALYZE when the contents of a table has changed significantly: a few percents of records in a table have been added, updated or deleted. It won't hurt to run ANALYZE just before or right after adding an index to a table. That sometimes helps query planner to properly use the new index.


VACUUM reclaims storage occupied by dead records. Dead records in a table are the deleted or the previous versions of updated records. Such records are only marked as unavailable but still occupy disk space, making table scans slower. VACUUM also has an option that tells it to ANALYZE the table.

There are two very different VACUUM versions. Just VACUUM command reorganises live records in a table and makes the allocated storage space available for new records. However, this storage space doesn't return to the operating system. This command can be run in parallel with other read and write operations on the table. VACUUM FULL exclusively locks the table, creates a new table file, copies only live records to this file, then deletes the old table file. The reclaimed storage space is returned to the system in this case. This command doesn't allow any other read and write operations on the vacuumed table.


Even though PostgreSQL can autovacuum tables itself after a certain number of rows gets marked as deleted, some developers prefer to run VACUUM ANALYZE on tables with a lot of read/write operations on a custom schedule. For example, at the least busy time of the day.

Use VACUUM when the contents of a table has changed significantly: a few percents of records in a table have been added, updated or deleted.


REINDEX rebuilds an existing index or all indexes for a table or entire database. This command is helpful when an index becomes corrupted and is not used anymore, or when an index gets bloated after significant changes in the table contents.


In my opinion, running VACUUM ANALYZE and then REINDEX commands on the biggest tables in the application database really helps to improve its performance.