설치·접속: PostgreSQL 설치와 접속
부제: 인덱스가 쌓이기만 하고 뭘 지워도 되는지 모를 때 — 한 번도 안 탄 인덱스와 겹치는 인덱스를 찾아낸다
-- 테이블별 인덱스 사용 횟수(idx_scan)와 크기를 나란히
SELECT indexrelname, idx_scan,
pg_size_pretty(pg_relation_size(indexrelid)) AS size
FROM pg_stat_user_indexes
WHERE relname = 'm5_orders'
ORDER BY idx_scan;
indexrelname | idx_scan | size
----------------------+----------+-------
idx_m5_amount_unused | 0 | 43 MB ← 한 번도 안 탐: 삭제 후보
idx_m5_uid_dup | 0 | 14 MB ← (user_id) 단독: 아래 복합과 중복
idx_m5_us | 8016 | 14 MB ← (user_id,status): 얘가 다 처리pg_stat_user_indexes.idx_scan은 그 인덱스가 누적 몇 번 스캔에 쓰였는지 카운트다. idx_scan = 0이면 통계 수집 이후 한 번도 안 탄 인덱스 — 읽기엔 도움 안 주면서 INSERT/UPDATE마다 갱신 비용만 물리고 디스크(여기선 43MB)를 잡아먹는 순수 부채다. 두 번째 idx_m5_uid_dup은 더 교묘하다: (user_id) 단독 인덱스인데, 복합 인덱스 idx_m5_us(user_id, status)가 user_id를 선두로 가지므로 user_id 조회를 이미 다 처리한다(그래서 idx_scan=0). 이런 선두 컬럼이 겹치는 중복 인덱스는 좁은 쪽을 지워도 된다. 단, 판단 전 두 가지를 확인한다 — (1) 통계가 리셋된 뒤 충분한 기간(월간 배치까지 한 사이클) 관찰했는가, (2) 그 인덱스가 UNIQUE 제약이나 FK를 떠받치고 있진 않은가. 이 둘만 통과하면 DROP INDEX CONCURRENTLY로 안전하게 걷어낸다.
이렇게도 쓴다
DB 전체에서 안 쓰는 인덱스를 낭비 크기 순으로 뽑는다. (조합: 전역 스캔)
SELECT relname, indexrelname, pg_size_pretty(pg_relation_size(indexrelid)) AS size
FROM pg_stat_user_indexes WHERE idx_scan = 0
ORDER BY pg_relation_size(indexrelid) DESC;
선두 컬럼이 겹치는 중복 인덱스를 정의로 찾아낸다. (조합: pg_indexes)
SELECT tablename, indexname, indexdef FROM pg_indexes
WHERE tablename='m5_orders' ORDER BY indexdef;
관찰을 새로 시작하려면 통계 카운터를 리셋한다. (조합: pg_stat_reset)
SELECT pg_stat_reset(); -- 이 시점부터 idx_scan 다시 0에서 누적
지울 땐 테이블 잠금 없이 동시 삭제한다. (조합: DROP INDEX CONCURRENTLY)
DROP INDEX CONCURRENTLY idx_m5_amount_unused;
UNIQUE·FK를 떠받치는 인덱스인지 먼저 확인한다(그러면 못 지운다). (조합: 제약 확인)
SELECT conname, contype FROM pg_constraint WHERE conindid = 'idx_m5_us'::regclass;
인덱스별 읽기 vs 쓰기 부담을 함께 봐 유지 가치를 판단한다. (조합: idx_tup_read)
SELECT indexrelname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes WHERE relname='m5_orders';'명령어 > DB' 카테고리의 다른 글
| [PostgreSQL] \watch 같은 쿼리를 주기적으로 반복 실행한다 (0) | 2026.08.02 |
|---|---|
| [PostgreSQL] DELETE 했는데 용량이 안 줄고 오히려 느려질 때 — VACUUM과 bloat (0) | 2026.08.02 |
| [PostgreSQL] pg_trgm GIN — `LIKE '%foo%'` 선행 와일드카드를 인덱스로 (0) | 2026.08.02 |
| [PostgreSQL] \timing 쿼리 실행 시간을 잰다 (0) | 2026.08.02 |
| [PostgreSQL] 디스크가 차오를 때 어디가 부었는지 찾기 — 테이블·인덱스 크기와 bloat (0) | 2026.08.02 |