본문 바로가기
C.W.K.
Stream
Lesson 10 of 10 · published

색인 전략: 적을수록 나을 때

~14 min · indexes, strategy

Level 0스키마 새싹
0 XP0/86 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

질의가 요구하는 색인만 만들어

색인은 읽기를 빠르게 하지만 INSERT·UPDATE·DELETE를 더 비싸게 만들고 디스크와 캐시를 차지하며 VACUUM 유지보수도 늘려. 측정 없이 색인을 더하면 읽기 질의는 눈에 띄게 빨라지지 않으면서 쓰기 처리량만 5배 낮아질 수 있어. 느린 질의를 측정하고 실행 계획에서 반복되는 조건과 정렬을 찾아 가장 큰 병목부터 해결해.

쓰이지 않는 색인을 찾아

pg_stat_user_indexes.idx_scan = 0은 후보를 찾는 단서야. 통계가 초기화된 시점, 월말 작업, 장애 대응처럼 드문 경로를 확인하지 않고 바로 지우지는 마.

겹치는 색인을 합쳐

복합 색인이 단일 색인의 역할을 대신하는지, 고유 제약을 받치는 색인인지 살펴. 읽기에 의미 있는 이득을 주지 못하면서 쓰기와 캐시만 잡아먹는 색인은 유지 이유를 설명해야 해.

Code

미사용 인덱스 찾기·sql
SELECT
    s.schemaname || '.' || s.relname AS table,
    s.indexrelname                   AS index,
    pg_size_pretty(pg_relation_size(s.indexrelid)) AS size,
    s.idx_scan                       AS times_used
FROM   pg_stat_user_indexes s
JOIN   pg_index i ON i.indexrelid = s.indexrelid
WHERE  NOT i.indisunique           -- unique 인덱스 절대 drop 안 함
ORDER  BY s.idx_scan, pg_relation_size(s.indexrelid) DESC;
-- 긴 기간 idx_scan = 0 인덱스가 drop 후보.
중복 인덱스 찾기·sql
-- 같은 컬럼 덮는 두 인덱스 = 순수 오버헤드
SELECT
    indrelid::regclass AS table,
    array_agg(indexrelid::regclass) AS indexes,
    array_agg(indkey) AS column_lists
FROM   pg_index
GROUP  BY indrelid, indkey
HAVING COUNT(*) > 1;
비대해진 색인을 다시 만드는 방법·sql
-- 무거운 churn 후 인덱스 bloat 가능. REINDEX 가 재구축.
REINDEX INDEX CONCURRENTLY orders_customer_idx;
-- CONCURRENTLY 가 긴 lock 회피; 프로덕션에 사용.

External links

Exercise

실제 데이터베이스에서 미사용 색인 질의를 실행해 제거 후보를 찾아. 코드 검색과 운영 주기를 확인해 드문 경로에서 쓰이지 않는지 검증한 뒤 트랜잭션 안에서 제거를 시험하고 문제가 생기면 ROLLBACK해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.