설치·접속: PostgreSQL 설치와 접속
부제: user_id 범위로 amount만 뽑는 조회가 잦은데, 인덱스는 탔지만 매번 테이블(heap)까지 다녀와 느릴 때
-- 검색 키는 user_id, 반환할 amount는 INCLUDE로 인덱스에 얹는다
CREATE INDEX idx_orders_uid_incl ON demo_orders(user_id) INCLUDE (amount);
SELECT user_id, amount FROM demo_orders WHERE user_id BETWEEN 100 AND 200;
-- 일반 인덱스 (user_id): 인덱스로 위치만 찾고 테이블 889블록을 또 읽음 → 891 buffers, 0.91 ms
Index Only Scan using idx_orders_uid_incl on demo_orders (actual time=0.006..0.081 rows=1015 loops=1)
Index Cond: ((user_id >= 100) AND (user_id <= 200))
Heap Fetches: 0
Buffers: shared hit=3 read=5
Execution Time: 0.122 ms일반 인덱스는 user_id로 행의 위치만 알려주고, 정작 amount 값을 읽으려면 테이블(heap)로 다시 가야 한다. 매칭 행이 많으면 이 heap 방문이 병목(891 buffers). INCLUDE (amount)로 amount를 인덱스 리프에 얹어두면 인덱스만 읽고 끝나는 Index Only Scan이 되고, Heap Fetches: 0이 그 증거다 — 891 buffers가 8 buffers로 준다. INCLUDE 컬럼은 검색/정렬에는 안 쓰이고 그저 실려만 가므로, 키에 넣기엔 부적절한(정렬 의미 없는) 반환용 컬럼에 적합하다. 함정 둘: 인덱스가 커지고(여기선 15MB), Index Only Scan은 visibility map이 최신이어야(=VACUUM이 돌아야) heap 방문 없이 동작한다.
이렇게도 쓴다
여러 반환 컬럼을 한꺼번에 실어 완전 커버링을 만든다.
CREATE INDEX idx_cover ON demo_orders(user_id) INCLUDE (amount, status, created_at);
INCLUDE 대신 복합 키로도 커버링이 되지만, 정렬 대상이 늘어난다. (비교)
CREATE INDEX idx_multi ON demo_orders(user_id, amount);
Index Only Scan이 되려면 VACUUM으로 visibility map을 갱신한다. (조합: VACUUM)
VACUUM demo_orders;
Heap Fetches가 0인지로 커버링 성공을 확인한다. (조합: EXPLAIN ANALYZE)
EXPLAIN (ANALYZE) SELECT user_id, amount FROM demo_orders WHERE user_id=150;
UNIQUE 제약을 유지하면서 반환 컬럼을 얹는다. (조합: UNIQUE INCLUDE)
CREATE UNIQUE INDEX uq_ord ON demo_orders(id) INCLUDE (amount);
인덱스가 얼마나 커졌는지 대가를 확인한다. (조합: pg_relation_size)
SELECT pg_size_pretty(pg_relation_size('idx_orders_uid_incl'));'명령어 > DB' 카테고리의 다른 글
| [PostgreSQL] earthdistance `<@>` — 두 좌표 직선거리를 한 줄로 (0) | 2026.08.01 |
|---|---|
| [PostgreSQL] CTE 최적화 울타리 WITH에 MATERIALIZED 붙였다가 느려질 때 (0) | 2026.08.01 |
| [PostgreSQL] \copy 쿼리 결과를 CSV로 내보내고 읽어들인다 (0) | 2026.08.01 |
| [PostgreSQL] COPY 수백만 행을 INSERT보다 빠르게 밀어 넣는다 (0) | 2026.08.01 |
| [PostgreSQL] 대량 적재 체크리스트 — COPY + 인덱스 후생성 + maintenance_work_mem + 단일 트랜잭션 + 후행 ANALYZE (0) | 2026.08.01 |