0Pricing
SQL Interview Prep · 강의

순차 스캔, 인덱스 스캔, 인덱스 전용 스캔 비교

플래너가 각각을 선택하는 이유와 이것이 쿼리에 관해 알려 주는 내용을 알아봅니다.

순차 스캔, 인덱스 스캔, 인덱스 전용 스캔 비교은(는) CoddyKit의 무료 SQL Interview Prep 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.

테이블을 읽는 세 가지 방법

플래너가 테이블에서 행을 가져와야 할 때는 세 가지 접근 방식 중 하나를 선택하며, 면접관은 이 세 가지를 모두 말할 수 있기를 기대합니다:

  • 순차 스캔, 테이블의 모든 행을 처음부터 끝까지 읽습니다.
  • 인덱스 스캔, 인덱스를 따라가며 일치하는 행을 찾은 다음 각 행을 테이블에서 가져옵니다.
  • 인덱스 전용 스캔, 테이블에 전혀 접근하지 않고 인덱스만으로 모든 결과를 처리합니다.

플래너가 각각을 왜 선택하는지 아는 것이 이 lesson의 핵심이며, 면접에서 반드시 나오는 숙련자 수준의 질문입니다.

순차 스캔의 동작

순차 스캔은 테이블의 페이지를 차례로 하나씩 읽고 각 행에 필터를 적용합니다. 인덱스는 참조하지 않습니다.

나쁘게 들리지만 올바른 선택인 경우가 많습니다. 순차 읽기는 디스크에서 빠르므로(무작위 이동이 없기 때문입니다), 쿼리가 테이블의 큰 비율을 반환할 때는 모든 항목을 스캔하는 것이 인덱스를 수백만 번 이동하는 것보다 효율적입니다.

예를 들어 orders를 스캔하고 amount > 100인 행만 남기는 경우입니다. 대부분의 주문 금액이 100을 초과한다면 순차 스캔이 올바른 선택입니다.

EXPLAIN SELECT * FROM orders WHERE amount > 100;

Seq Scan on orders  (cost=0.00..18334.00 rows=900000 width=64)
  Filter: (amount > 100)

인덱스 스캔의 동작

인덱스 스캔은 B-트리를 사용해 일치하는 키로 바로 이동한 다음 테이블 힙에서 해당 행을 읽습니다.

필터의 선택도가 높아 테이블의 작은 일부만 반환할 때 특히 효과적입니다. 인덱스로 5개 행을 찾는 것이 1천만 개를 읽는 것보다 빠릅니다.

실행 계획에는 사용한 인덱스의 이름이 표시됩니다. 일치하는 각 행마다 인덱스 조회 한 번과 힙 가져오기 한 번(무작위 읽기)이 필요하므로, 너무 많은 행을 반환하면 인덱스 스캔의 장점이 사라집니다.

EXPLAIN SELECT * FROM orders WHERE customer_id = 42;

Index Scan using idx_orders_customer on orders
  (cost=0.42..38.50 rows=12 width=64)
  Index Cond: (customer_id = 42)

선택도가 선택을 결정합니다

이 모든 것을 좌우하는 단 하나의 개념은 선택도입니다. 즉, 조건식이 유지하는 행의 비율입니다.

  • 높은 선택도(일치하는 행이 적음, 고유 id 등)는 인덱스 스캔에 유리합니다.
  • 낮은 선택도(일치하는 행이 많음, status IS NOT NULL 등)는 순차 스캔에 유리합니다.

일반적인 기준으로, 쿼리가 테이블의 약 5~10%보다 많은 행을 반환하면 플래너는 순차 스캔을 선호하는 경우가 많습니다. 인덱스를 사용할 때 발생하는 무작위 힙 가져오기가 테이블 전체를 순서대로 읽는 것보다 비싸지기 때문입니다.

인덱스 전용 스캔

인덱스 전용 스캔은 세 가지 방식 중 가장 빠릅니다. 쿼리에 필요한 모든 열이 이미 인덱스에 들어 있다면, 엔진은 테이블 힙에 전혀 접근하지 않습니다.

예제 쿼리는 customer_id만 선택하고 이를 기준으로 필터링하며, 인덱스도 customer_id에 만들어져 있습니다. 필요한 모든 데이터가 인덱스에 있으므로 Postgres는 인덱스 전용 스캔을 보고합니다.

이 방식은 일반 인덱스 스캔을 느리게 만드는 무작위 힙 읽기를 피하므로, 열이 많은 테이블에서 큰 성능 향상을 얻을 수 있습니다.

EXPLAIN SELECT customer_id FROM orders WHERE customer_id = 42;

Index Only Scan using idx_orders_customer on orders
  (cost=0.42..8.44 rows=12 width=4)
  Index Cond: (customer_id = 42)

가시성 맵의 함정

면접관이 이 세부 사항을 특히 좋아합니다. 인덱스 전용 스캔도 각 행이 현재 트랜잭션에서 보이는지(MVCC) 확인해야 하며, 인덱스 자체에는 가시성 정보가 저장되지 않습니다.

Postgres는 가시성 맵을 사용합니다. 페이지가 모든 행이 보이는 상태로 표시되어 있으면 힙을 건너뛰고, 그렇지 않으면 어쨌든 힙의 행을 가져와야 합니다. 실행 계획에는 Heap Fetches: N으로 표시됩니다.

따라서 방금 갱신된 테이블에서는 힙 가져오기가 많이 발생해 인덱스 전용 스캔이 느려질 수 있으며, VACUUM이 가시성 맵을 갱신할 때까지 이러한 현상이 계속됩니다.

Index Only Scan using idx_orders_customer on orders
  (actual time=0.01..0.03 rows=12 loops=1)
  Heap Fetches: 0

비트맵 스캔: 중간 지점

자주 나타나는 네 번째 방식도 있습니다. 바로 비트맵 힙 스캔입니다. 플래너는 일반 인덱스 스캔이 처리하기에 적합한 행보다 많지만 전체 테이블보다는 적은 행과 일치하는 조건식에 이 방식을 선택합니다.

먼저 인덱스에서 일치하는 행의 위치를 비트맵으로 만들고(비트맵 인덱스 스캔), 그다음 무작위 순서가 아니라 물리적 순서로 힙 페이지를 가져옵니다. 순서가 정해진 가져오기는 일반 인덱스 스캔에서 발생하는 흩어진 읽기보다 훨씬 저렴합니다.

Bitmap Heap Scan on orders  (cost=12.0..520.0 rows=8000)
  Recheck Cond: (status = 'pending')
  ->  Bitmap Index Scan on idx_orders_status
        (cost=0..12 rows=8000)
        Index Cond: (status = 'pending')

플래너가 인덱스를 무시한 이유

면접에서 자주 나오는 질문입니다: 인덱스를 추가했는데도 실행 계획이 순차 스캔을 수행합니다. 왜 그럴까요? 일반적인 이유는 다음과 같습니다:

  • 조건식의 선택도가 높지 않아서 스캔하는 편이 실제로 더 저렴합니다.
  • 열을 함수로 감쌌기 때문입니다: WHERE lower(email) = ...은 email에 만든 일반 인덱스를 사용할 수 없습니다.
  • 자료형이 일치하지 않아서 인덱스를 무효화하는 암시적 형 변환이 발생합니다.
  • 통계 정보가 오래되었습니다. ANALYZE를 실행하십시오.
  • 테이블이 매우 작기 때문입니다. 몇 개의 페이지만 스캔하는 것이 인덱스 사용에 따른 추가 비용보다 빠릅니다.

진단 예제

orders에 created_at 인덱스가 있지만 다음 쿼리가 여전히 순차 스캔을 수행한다고 가정해 보겠습니다:

원인은 DATE(created_at)입니다. 열을 함수로 감싸면 원본 created_at에 만든 인덱스를 사용할 수 없습니다. 해결 방법은 열을 그대로 둔 범위 조건식으로 다시 작성하거나, DATE(created_at)에 대한 표현식 인덱스를 만드는 것입니다.

-- Slow: function on the indexed column
WHERE DATE(created_at) = '2026-01-01'

-- Fast: bare column, range uses the index
WHERE created_at >= '2026-01-01'
  AND created_at <  '2026-01-02'

방식 비교하기

면접을 위해 다음 비교를 기억해 두십시오:

  • 순차 스캔, 많은 비율의 행을 반환할 때 가장 적합하며 순차 입출력을 사용합니다.
  • 인덱스 스캔, 선택도가 높은 조회에 가장 적합하며 인덱스 순회와 무작위 힙 가져오기를 사용합니다.
  • 비트맵 힙 스캔, 중간 정도의 일치 행 수에 적합하며 인덱스로 비트맵을 만든 뒤 순서가 정해진 힙 읽기를 수행합니다.
  • 인덱스 전용 스캔, 인덱스가 필요한 모든 열을 포함하고 페이지가 모두 보이는 상태일 때 가장 빠릅니다.

플래너는 주로 선택도와 통계 정보에 따라 예상 비용을 계산하여 방식을 선택합니다.

테스트 강제하기(운영 환경에서 하지 않는 이유)

개발 환경에서 특정 요점을 확인하려면 플래너의 선택을 일시적으로 유도할 수 있습니다: SET enable_seqscan = off;는 플래너가 인덱스를 우선하도록 하므로 실행 계획을 비교할 수 있습니다.

이는 진단용 요령일 뿐, 운영 환경의 해결책이 아닙니다. 면접에서는 실제 해결책이 통계 정보 개선, 적절한 인덱스 추가, 조건식 재작성이지 플래너 기능을 전역적으로 비활성화하는 것이 아니라고 말하십시오.

SET enable_seqscan = off;
EXPLAIN ANALYZE SELECT * FROM orders WHERE amount > 100;
SET enable_seqscan = on;

빠른 확인

쿼리가 email만 선택하고 email을 기준으로 필터링하며, email에 B-트리 인덱스가 있습니다. 실행 계획에는 Index Only Scan이 표시됩니다. 일반 인덱스 스캔보다 이 방식이 빠른 이유는 무엇입니까?

복습

접근 방식에 대한 핵심 내용입니다:

  • 순차 스캔은 선택도가 낮은 쿼리에서 유리하고, 인덱스 스캔은 선택도가 높은 쿼리에서 유리합니다.
  • 인덱스 전용 스캔은 인덱스가 필요한 모든 열을 포함할 때 힙 접근을 피합니다. Heap Fetches와 가시성 맵을 확인하십시오.
  • 비트맵 힙 스캔은 힙 페이지를 물리적 순서로 가져와 두 방식의 중간 지점을 제공합니다.
  • 플래너는 선택도와 통계 정보에 따라 결정합니다. 열에 적용한 함수, 자료형 불일치, 오래된 통계 정보 때문에 인덱스가 무시될 수 있습니다.

자주 묻는 질문

“순차 스캔, 인덱스 스캔, 인덱스 전용 스캔 비교” 강의는 무료인가요?

네 — “순차 스캔, 인덱스 스캔, 인덱스 전용 스캔 비교” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Interview Prep 강의 전체를 잠금 해제할 수 있습니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.

“순차 스캔, 인덱스 스캔, 인덱스 전용 스캔 비교”에서 뭘 배우나요?

플래너가 각각을 선택하는 이유와 이것이 쿼리에 관해 알려 주는 내용을 알아봅니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

SQL Interview Prep을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 SQL Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“순차 스캔, 인덱스 스캔, 인덱스 전용 스캔 비교” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 SQL Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 SQL Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. EXPLAIN 계획 읽기
  2. 순차 스캔, 인덱스 스캔, 인덱스 전용 스캔 비교
  3. 조인 알고리즘: 중첩 루프, 해시, 병합
  4. 느린 쿼리 찾기와 수정
← SQL Interview Prep(으)로 돌아가기