1.Why Indexes Speed Reads but Increase Storage and Write Cost
An index is a separate, ordered structure that lets PostgreSQL find matching rows without scanning the whole table — but that structure is itself real data that must be stored on disk and kept in sync with every INSERT, UPDATE (of an indexed column) and DELETE, so more indexes means faster reads at the direct cost of more storage and slower writes.
Key features
- An index is a separate on-disk structure, occupying its own storage in addition to the table itself
- Every INSERT must add an entry to every index on the table, not just write the row
- Every UPDATE that changes an indexed column must update that index too (and, per the Storage and Table Internals section, disqualifies that update from the cheaper HOT path)
- Every DELETE eventually requires cleanup in every index referencing the deleted row, alongside the heap cleanup
- More indexes on a table directly means more write amplification — each logical write becomes several physical writes
What each index costs, per relevant write
- No index
- INSERT/UPDATE/DELETE touch only the table
- No extra storage
- Reads must scan every row
- With an index
- Every write also updates the index
- Extra on-disk storage, maintained in lockstep
- Matching reads skip straight to the row
Command
-- storage cost is directly observable
SELECT pg_size_pretty(pg_relation_size('accounts')) AS table_size,
pg_size_pretty(pg_indexes_size('accounts')) AS all_indexes_size;An index is a real, separate on-disk structure that must be kept in sync with every write — more indexes means faster reads for queries that use them, but more storage and slower INSERT/UPDATE/DELETE for everything else. Add indexes based on confirmed query patterns, not speculative "might need it" coverage.