VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
행 조회의 동작 방식(그리고 비용이 큰 이유)
일반적인 인덱스 조회는 두 단계입니다:- MySQL이 인덱스를 검색하여 어떤 행이 일치하는지 찾습니다
- 일치하는 각 행에 대해 MySQL이 테이블에서 전체 행을 가져옵니다(“행 조회” 또는 “테이블 복귀 조회”)
EXPLAIN에서 커버링 인덱스 식별하기
EXPLAIN은 커버링 인덱스가 사용 중일 때 알려줍니다: Extra: Using index를 찾으세요. EXPLAIN 출력에 아직 익숙하지 않다면 MySQL에서 EXPLAIN 읽기가 모든 핵심 열을 다룹니다.
Using index — MySQL이 인덱스만 읽었습니다. 행 조회가 없습니다.
이제 인덱스에 없는 열을 추가해 보세요:
Extra가 비어 있습니다 — MySQL은 인덱스로 행을 찾은 다음 order_total을 얻기 위해 전체 행을 가져옵니다. 행 조회가 돌아왔습니다.
커버링 인덱스 설계하기
목표는 쿼리가 건드리는 모든 열 —WHERE, ORDER BY, GROUP BY, SELECT 목록에 있는 열 — 을 포함하는 것입니다. 열 순서는 WHERE와 ORDER BY 필터링에 대해 여전히 최좌측 접두사 규칙을 따릅니다:
user_id가 첫 번째 — 동등 필터created_at이 두 번째 — 정렬 열(인덱스가 이미 정렬되어 있어 filesort 없음)status가 마지막 —SELECT에만 있고 필터링이나 정렬에는 없음
SELECT 열은 어떤 행이 찾아지는지나 어떤 순서인지에 영향을 주지 않기 때문에 마지막에 옵니다 — 그저 따라가는 것뿐입니다.
커버링 인덱스가 가치 있는 경우
자주 묻는 질문
커버링 인덱스가 SELECT *에 도움이 되나요?
아니요. 인덱스는 SELECT 목록의 모든 열을 포함할 때만 쿼리를 커버할 수 있습니다. SELECT *는 모든 열을 선택하므로 모든 열을 인덱싱해야 하는데, 그 시점에는 사실상 테이블을 인덱스로 복제한 것이어서 유용하지 않습니다.
커버링 인덱스가 그래도 SELECT * 쿼리 속도를 높일 수 있나요?
예, 부분적으로는 그렇습니다. MySQL이 행 조회를 해야 하더라도 인덱스가 가져올 행의 범위를 좁혀 줍니다. 개선은 WHERE 필터링에서 오는 것이지 행 조회를 없애는 데서 오는 것이 아닙니다.
커버링 인덱스가 도움이 될지 어떻게 알 수 있나요?
EXPLAIN을 실행하고 Extra를 확인하세요. Using index condition이 보이거나 아무것도 없고(Using index 없음) rows가 크다면 커버링 인덱스가 도움이 될 수 있습니다. EXPLAIN ANALYZE는 실제 행 수와 추정 행 수를 보여 주므로 옵티마이저의 선택을 확인하는 데 유용합니다.
문제 해결
함께 보기
- MySQL 인덱스의 동작 방식 — 커버링 인덱스의 바탕이 되는 B-트리 기초
- MySQL에서 EXPLAIN 읽기 — EXPLAIN 출력에서
Using index를 확인하는 방법 - InnoDB의 데이터 저장 방식 — 행 조회의 비용이 큰 이유와 커버링이 이를 피하는 이유