인덱스 퀴즈 해설

[38번] 커버링 인덱스 (3)

index-quiz 2025. 12. 5. 14:41

#38

문제

 

다음과 같은 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로 인덱스를 활용하지 않고 테이블 풀스캔이 일어나고 있음을 확인할 수 있습니다.