디비에서 인덱스는 자주 활용되는 기능입니다.
대용량의 데이터에서 빠른 조회를 위해 인덱스는 반드시 설정해야 합니다.
하지만 지나친 인덱스 설정은 입력 시간을 지연시키고, 디비 용량을 커지게 합니다.
데이터를 입력할 때 테이블 외에 인덱스도 지정되면서 시간 지연과 용량 증가는 당연히 따라옵니다.
그래서 적절한 인덱스 활용 정책이 필요합니다.
오늘은 그 중에서 복합인덱스와 단일 조건의 관계에 대해 알아보겠습니다.
인덱스는 크게 단일인덱스
와 복합인덱스
로 구분할 수 있습니다.
단일인덱스는 하나의 컬럼으로 구성된 인덱스입니다.
하나의 컬럼을 기준으로 인덱싱 되기 때문에 활용 또한 단순합니다.
복합인덱스는 2개 이상의 컬럼으로 구성된 인덱스입니다.
그래서 쿼리 조건이나 정렬에 따라 인덱스 성능이 달라지게 됩니다.
제대로 인덱스 설정을 하면 Index Range Scan
으로 빠른 조회가 가능합니다.
하지만 잘못된 인덱스 설정을 할 경우, Table Full Scan
이 일어날 수 있습니다.
이 때는 인덱스 설정의 의미가 없고, 그냥 테이블을 조회하는 것과 동일한 성능을 보입니다.
간단한 예제를 보겠습니다.
테이블을 생성하고 인덱스를 설정했습니다.
CREATE TABLE category ( one_code bigint, one_name text, two_code bigint, two_name text, three_code bigint, three_name text ); CREATE INDEX category_ix ON category (one_code, two_code, three_code);
이제 생성한 테이블을 조회해 보겠습니다.
참고로 인덱스 스캔의 종류는 Range, Unique, Full, Fast Full, Skip 등 다양하게 있습니다.
여기서는 간단하게 Range Scan과 Full Scan으로 구분해 보겠습니다.
1. SELECT one_name FROM category WHERE one_code = 1; 2. SELECT two_name FROM category WHERE two_code = 2 3. SELECT three_name FROM category WHERE three_code = 3; # 결과 1. Range Scan 2. Full Scan 3. Full Scan
1. SELECT one_name FROM category WHERE one_code = 1 AND two_code = 2; 1. SELECT one_name FROM category WHERE one_code = 1 AND three_code = 3; 2. SELECT two_name FROM category WHERE two_code = 2 AND three_code = 3; # 결과 1. Range Scan 2. Range Scan + Filter 3. Full Scan
결과 값이 이해가 가시나요? 생각보다 간단합니다.
Optimizer
가 데이터를 스캔하는 방식은 복합인덱스로 지정된 컬럼의 순서입니다.
순차적으로 검색을 하면 Index Range Scan
방식을 사용합니다.
다음으로 선두 컬럼을 조건절 앞에 지정하고 뒤에는 순서에 맞지 않는 컬럼이 지정되면,
선두 컬럼을 Index Range Scan
후에 마지막 컬럼은 Filter
조회를 하게 됩니다.
마지막으로 선두 컬럼 자체를 생략하면, 처음부터 Index Full Scan
이 일어나게 됩니다.