ONE QUESTION AT A TIME.

천천히 생각하고, 분명하게.

TODAY’S QUESTION363 / 1500
데이터베이스난이도 중하5분 답변 목표 · 보강본

조회 컬럼을 모두 인덱스에 넣었는데도 테이블 접근이 남습니다. covering index와 index-only scan은 왜 같지 않을 수 있나요?

잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?

답변과 점검 포인트 펼치기답변 접기
01

구두 답변

정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.

필요한 컬럼이 인덱스에 있다는 것은 데이터 측면의 covering 조건이고, 실제 테이블 접근을 생략할 수 있는지는 엔진의 가시성·저장 구조와 실행 계획에 달려 있습니다. 인덱스를 넓혔다고 모든 조회가 인덱스만 읽는 것은 아닙니다.

동작 원리와 전제

PostgreSQL에서는 인덱스에 값이 있어도 MVCC 가시성을 확인하려고 heap을 읽을 수 있고 visibility map 상태가 중요합니다. 갱신이 잦아 all-visible 조건이 바뀌면 index-only scan의 heap fetch가 늘 수 있습니다. 다른 엔진의 클러스터링·버전 검사는 별도 계약입니다.

선택과 실패 처리

INCLUDE나 키 컬럼 추가는 읽기 lookup을 줄일 수 있지만 페이지 폭·캐시·쓰기 로그·갱신 비용을 늘립니다. 인덱스 크기가 커져 같은 메모리에 덜 들어가면 읽기 이점도 줄 수 있습니다. 반환 컬럼을 전부 넣기보다 자주 호출되는 좁은 질의부터 평가합니다.

구체적인 사례와 검증

실행 계획에 Index Only Scan이 표시돼도 실제 Heap Fetches가 많으면 가시성 확인 비용이 남습니다. 최근 갱신이 잦은 페이지와 오래 읽기 전용인 페이지를 나눠 비교하면 왜 같은 인덱스가 다른 성능을 보이는지 알 수 있습니다. 반대로 모든 컬럼을 키로 넣으면 정렬 구조와 쓰기 비용까지 늘어나므로 INCLUDE의 역할과 차이를 확인합니다. 인덱스 전용 조회를 목표로 vacuum을 공격적으로 늘리기 전에 원래 질의가 반환하는 데이터량과 사용 빈도를 봅니다. 작은 개선을 위해 전체 쓰기 workload의 로그와 페이지 분할을 크게 늘리지 않는지 대표 부하에서 검증하겠습니다.

계획 이름만 보지 않고 heap fetch·논리 읽기·반환량·쓰기 p99를 비교합니다. vacuum 상태와 콜드·웜 캐시, 최근 갱신된 행을 포함해 시험합니다. covering은 구조적 가능성이고 실제 인덱스 전용 접근은 현재 데이터와 엔진 상태에 대한 결과입니다.

02

득점 포인트

이해가 드러나는 지점을 확인해 보세요.

  • 핵심 구분: 필요한 컬럼이 인덱스에 있다는 것은 데이터 측면의 covering 조건이고, 실제 테이블 접근을 생략할 수 있는지는 엔진의 가시성·저장 구조와 실행 계획에 달려 있습니다.
  • 선택 조건: INCLUDE나 키 컬럼 추가는 읽기 lookup을 줄일 수 있지만 페이지 폭·캐시·쓰기 로그·갱신 비용을 늘립니다.
  • 검증 기준: 계획 이름만 보지 않고 heap fetch·논리 읽기·반환량·쓰기 p99를 비교합니다.
03

감점 포인트

놓치기 쉬운 조건과 오해를 짚어 보세요.

  • 조회 컬럼이 모두 인덱스에 있으면 테이블 접근은 항상 0이라고 한다.
04

더 파고들 거리

하나 더 질문하며 이해의 범위를 넓혀 보세요.

  • 인덱스에서 키를 찾은 뒤 원본 행을 다시 읽는 비용은 저장 구조에 따라 어떻게 달라지나요?
  • 오래된 읽기가 유지될 때 삭제한 튜플을 언제 재사용할 수 있으며 파일 축소와는 어떻게 다른가요?
  • 동일 SQL의 비용이 달라졌다면 추정 행·실제 행·파라미터·대기를 어떤 순서로 비교하나요?

득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.

원리부터 공부하고 싶다면

답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.

← 전체 질문 보기