일반적으로 인덱스를 설계한다고하면 Show
인덱스는 데이터를 효율적으로 찾는 방법이지만, MySQL의 경우 인덱스안에 포함된 데이터를 사용할 수 있으므로 이를 잘 활용한다면 실제 데이터까지 접근할 필요가 전혀 없습니다. 이처럼 쿼리를 충족시키는 데 필요한 모든 데이터를 갖고 있는 인덱스를 커버링 인덱스 (Covering Index 혹은 Covered Index) 라고합니다.
1-1. 커버링 인덱스 기본 지식커버링 인덱스의 예제를 보기전에 기본 지식을 먼저 익히고 넘어가겠습니다. 1-1-1. Using index먼저, 커버링 인덱스가 적용되면 아래와 같이 EXPLAIN 결과 (실행 계획) 의 Extra 필드에 "Using index" 가 표기됩니다. 여기서 index가 표기되는 여러 항목들과 비교하면 다음과 같은 차이점이 있습니다.
인덱스 풀 스캔이 발생하는 경우는 아래와 같습니다.
1-1-2. Non Clustered Key와 Clustered Key
Non Clustered Key와 Clustered Key를 통한 탐색은 다음과 같이 진행됩니다.
위 그림에선 2가지를 보셔야하는데요.
MySQL에서는 Non Clustered Key에
Clustered Key가 항상 포함되어 있습니다. 즉, 인덱스 조건에 부합한
커버링 인덱스는 여기서 "2. 실제 데이터 접근" 의 행위 없이 인덱스에 있는 컬럼값들로만 쿼리를 완성하는 것을 이야기 합니다. 자 이 내용을 숙지 하신뒤, 다음의 예제를 확인해보겠습니다. 1-2. SELECT테스트용 테이블의 이름은 temp_ad_offset 입니다. 인덱스 (customer_id 컬럼만 존재)가 있을 경우, 아래의 쿼리는 어떻게 작동될까요?
실행 계획을 돌려보면 다음과 같습니다. 혹시나 실행 계획을 처음 보신다면 각 항목은 다음과 같습니다.
실행 계획의 결과는 일반적인 인덱스가 where절에 사용된 경우로 출력 됩니다. 자 그럼 여기서 쿼리의 select 절을
앞선 결과와 다르게 Extra 항목에
자 이제 다양한 상황을 확인해보겠습니다. 1-3. WHERE + GROUP BY먼저 GROUP BY 에서 인덱스는 아래 조건에서 적용됩니다.
여기서 즉, 아래 2개의 쿼리는 모두 정상적으로 인덱스가 적용 됩니다.
그렇다면 WHERE의 조건이 동등 비교가 아닌 경우엔 어떻게 될까요? 1-3-1. WHERE가 동등 비교가 아닌 경우먼저 동등 비교의 실행
계획을 확인해봅니다.
해당 쿼리의 실행 계획은 아래와 같습니다. 1-2 에서 소개한 실행 계획과 거의 유사한 결과가 나왔습니다.
전체 수행 시간은 5.683초가 소요되었습니다. 이번엔 WHERE의 조건만
실행 계획은 다음과 같이 나왔습니다.
GROUP BY가 제대로 인덱스를 타지 못한것 같습니다. 1분 17초가 수행되었습니다.
실행 계획에서는 커버링 인덱스가 잘 수행된 것을 확인할 수 있습니다. 수행 시간은 1.6초로 기존 (5.683초) 대비 5배 이상 개선되었습니다. WHERE 뿐만 아니라, GROUP BY절, SELECT절 역시 인덱스를 타게 되면 얼마나 성능이 개선되는지 알게 되었습니다! 1-4. 마무리이번 포스팅에서는 커버링 인덱스의 기반 지식들과, SELECT, WHERE, GROUP BY 등의 인덱스 방식 등을 배워보았습니다. |