dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Scripts Library/postgresql/#4
Script #4
postgresql
Performanceread-onlyMin Version: 9.2

Find Unused Indexes in PostgreSQL

Lists never-scanned indexes that are neither unique nor primary keys, with their sizes. Surfaces cleanup candidates to cut write overhead and disk usage.

#index#unused-index#pg_stat_user_indexes#cleanup
postgresql · sql
SELECT s.schemaname, s.relname AS table_name, s.indexrelname AS index_name,
       s.idx_scan,
       pg_size_pretty(pg_relation_size(s.indexrelid)) AS index_size
FROM pg_stat_user_indexes s
JOIN pg_index i ON i.indexrelid = s.indexrelid
WHERE s.idx_scan = 0
  AND NOT i.indisunique
  AND NOT i.indisprimary
ORDER BY pg_relation_size(s.indexrelid) DESC
LIMIT 30;
Operational Notes & Remediation Guidance

Statistics reflect usage since the last reset (`pg_stat_database.stats_reset`). Also check indexes used on replicas. Always drop with `DROP INDEX CONCURRENTLY`.

Production Safety & Execution Standards
  • This script is designed for read-only diagnostics; it does not alter schema or modify data directly.
  • Prior to executing on production systems under high load, verify the target database version (Min. Version: 9.2).
  • Exercise caution with mutating actions (e.g., terminating sessions or dropping indexes) referenced in the notes section.