핵심 답변
인덱스 스킵 스캔은 WHERE 조건 처리를 위해 인덱스 앞부분을 건너뛰고, 루스 인덱스 스캔은 GROUP BY 처리를 위해 그룹 내 레코드를 건너뜁니다.

이름은 비슷하지만 완전히 다른 최적화 기법입니다:

둘 다 "건너뛴다"는 공통점이 있지만, 건너뛰는 대상과 목적이 전혀 다릅니다.

알아야 할 배경 개념

복합 인덱스의 제약

복합 인덱스 INDEX(A, B, C)는 왼쪽부터 순서대로 사용해야 합니다:

이 제약을 완화하는 것이 인덱스 스킵 스캔입니다.

GROUP BY의 비용

GROUP BY는 보통 모든 레코드를 읽어 그룹핑하는데, 인덱스가 이미 정렬되어 있다면 각 그룹의 대표값만 읽을 수 있습니다. 이것이 루스 인덱스 스캔입니다.

더 깊이 파고들기

핵심 차이점 비교

구분 인덱스 스킵 스캔 루스 인덱스 스캔
도입 버전 MySQL 8.0.13+ MySQL 5.0+ (오래됨)
주요 용도 WHERE 조건 처리 GROUP BY 처리
해결 문제 인덱스 앞 컬럼 없는 쿼리 그룹별 MIN/MAX 구하기
건너뛰는 대상 앞 컬럼의 고유값들 같은 그룹의 레코드들
EXPLAIN 표시 Using index for skip scan Using index for group-by
사용 조건 앞 컬럼 카디널리티 낮음 MIN/MAX만 사용, 왼쪽 접두사

인덱스 스킵 스캔 상세

복합 인덱스 INDEX(gender, birth_date)에서:

-- gender 조건 없이 birth_date만 검색
SELECT * FROM users WHERE birth_date = '1990-01-01';

-- 내부적으로 다음처럼 변환됨:
WHERE gender='M' AND birth_date='1990-01-01'
UNION ALL
WHERE gender='F' AND birth_date='1990-01-01'

gender의 고유값('M', 'F')을 자동으로 순회하면서 각각 인덱스 검색을 수행합니다.

루스 인덱스 스캔 상세

복합 인덱스 INDEX(category_id, price)에서:

-- 각 카테고리의 최소 가격 구하기
SELECT category_id, MIN(price)
FROM products
GROUP BY category_id;

인덱스가 이미 category_id로 정렬되어 있고, 같은 category_id 내에서 price가 정렬되어 있으므로, 각 카테고리의 첫 레코드만 읽으면 MIN 값을 알 수 있습니다.

언제 각각 사용되나?

스킵 스캔:

루스 스캔:

시각화
인덱스 스킵 스캔 INDEX(gender, age) WHERE age=25 스킵! gender='M' 구간 age=25 검색 → 결과 반환 gender='F' 구간 age=25 검색 → 결과 반환 루스 인덱스 스캔 INDEX(cat_id, price) GROUP BY cat_id, MIN(price) cat_id=1 그룹 price: 100, 150, 200... ✓ 첫 레코드(100) 나머지 스킵 핵심 차이 스킵 스캔 • 목적: WHERE 절 최적화 • 대상: 인덱스 앞 컬럼의 값들 • 조건: 앞 컬럼 카디널리티 낮음 • 예: gender 2개 값 순회 루스 스캔 • 목적: GROUP BY 최적화 • 대상: 그룹 내 나머지 레코드 • 조건: MIN/MAX만 사용 • 예: 각 그룹 첫 레코드만

스킵 스캔은 앞 컬럼 값을 순회하고, 루스 스캔은 그룹 내 레코드를 건너뜁니다.

함께 알면 좋은 개념