
문제
다음과 같은 test_table이 있다.
CREATE TABLE test_table (
id INT PRIMARY KEY,
name VARCHAR(100),
age INT,
address VARCHAR(200),
Index idx_name_age(name, age)
);
다음 쿼리를 실행할 때 실행계획에 대한 서술로 옳은 것을 고르시오.
SELECT * FROM test_table WHERE age > 0;
선지
A) idx_name_age를 활용하지 않는다.
B) idx_name_age 인덱스 스캔만 일어나고 테이블 스캔은 일어나지 않는다.
C) idx_name_age를 스캔한 이후, 테이블 스캔이 일어난다.
정답
A) idx_name_age를 활용하지 않는다.
B) idx_name_age 인덱스 스캔만 일어나고 테이블 스캔은 일어나지 않는다.
C) idx_name_age를 스캔한 이후, 테이블 스캔이 일어난다.
핵심 해설
커버링 인덱스는 2가지 조건을 만족해야 합니다.
- 조회하는 모든 컬럼이 인덱스에 존재
- 조건절에 포함된 컬럼이 인덱스 테이블에 존재
그러므로, test_table의 전체 행을 가져오는 쿼리는 커버링 인덱스 상황 아닙니다.
- idx_name_age 인덱스 테이블에 없는 address 컬럼이 같이 조회되어야 합니다.
따라서 인덱스를 활용한 두번의 걸친 탐색보다 한번의 테이블 풀스캔을 더 효율적이라고 판단합니다.
상세 해설
주어진 쿼리는 커버링 인덱스가 아니므로 테이블 데이터의 접근이 필수적입니다.
옵티마이저는 인덱스를 활용한 두번에 걸친 탐색보다 테이블 풀스캔을 통한 한번의 탐색이 더 효율적이라 판단합니다.

- idx_name_age 인덱스는 name을 기준으로 Left-most 정렬되어 있습니다. 따라서 인덱스를 활용하려면 idx_name_age를 모두 순차 탐색하면서 필터링하고, 테이블을 2차 탐색하여 데이터를 모두 가져와야 합니다. 그러나 이렇게 2차 탐색하는 것의 비용을 옵티마이저는 테이블 접근보다 4-5배 정도 높게 평가합니다. 따라서 아예 테이블의 모든 행을 순회하면서 where 절을 활용해 필터링하는 것이 더 저렴하다고 평가합니다. (Using where)
실행계획 확인하기
+--+-----------+----------+----------+----+-------------+----+-------+----+-----+--------+-----------+
|id|select_type|table |partitions|type|possible_keys|key |key_len|ref |rows |filtered|Extra |
+--+-----------+----------+----------+----+-------------+----+-------+----+-----+--------+-----------+
|1 |SIMPLE |test_table|null |ALL |null |null|null |null|97588|33.33 |Using where|
+--+-----------+----------+----------+----+-------------+----+-------+----+-----+--------+-----------+
type : ALL로 인덱스를 활용하지 않고 테이블 풀스캔이 일어나고 있음을 확인할 수 있습니다.
'인덱스 퀴즈 해설' 카테고리의 다른 글
| [40번] Unique Index Null 중복 허용 (0) | 2025.12.05 |
|---|---|
| [39번] count(*) 풀 인덱스 스캔 (0) | 2025.12.05 |
| [37번] 커버링 인덱스 (2) (0) | 2025.12.05 |
| [36번] 커버링 인덱스 (1) (0) | 2025.12.05 |
| [35번] 인덱스 루스 스캔 TF (3) (0) | 2025.10.31 |