Database 복합 인덱스를 사용하는 이유

관계형 데이터베이스에서 인덱스는 쿼리 성능을 향상시키기 위해 사용한다. 인덱스는 하나의 컬럼에 생성되는 단일 인덱스와 두 개 이상의 컬럼에 생성되는 복합 인덱스로 구분할 수 있다.

가령 이건 단일 인덱스 생성이다.

CREATE INDEX idx_department_id ON employees (department_id);

그리고 이건 복합 인덱스 생성이다.

CREATE INDEX idx_department_role ON employees (department_id, role_id);

이때 한 가지 의문이 생기는데

CREATE INDEX idx_department_id ON employees (department_id);
CREATE INDEX idx_department_role_id ON employees (role_id);

이렇게 단일 인덱스를 나눠서 생성하는 거랑

CREATE INDEX idx_department_role ON employees (department_id, role_id);

이렇게 복합 인덱스를 한 번에 생성하는 게 차이가 있나? 라는 것이다.

1. 복합 인덱스

당연히 차이가 있으니까 복합 인덱스라는 게 있는 것이다.

복합 인덱스는 where 절에 and 로 여러 개의 컬럼의 조건을 만족시키는 쿼리를 수행할 때 유리하다.

예를 들어 아래의 테이블에

database composite index (1)

복합 인덱스를 생성했다.

CREATE INDEX idx_department_role ON employees (department_id, role_id);
database composite index (2)

이런 테이블 구조에서 아래와 같은 필터링 조건을 만족시킬 때 유리하다.

SELECT * FROM employees WHERE department_id = 20 AND role_id = 101;

explain으로 확인해보면

database composite index (3)

department_id과 role_id를 동시 조건으로 사용하는 인덱스 스캔을 하는 걸 볼 수 있다.

2. 단일 인덱스

같은 테이블에 복합 인덱스 대신 단일 인덱스 여러 개를 만들어 비교해본다.

database composite index (5)

이번엔 비트맵 힙 스캔 방식을 사용하는 걸 볼 수 있는데 먼저 role_id에 대해서만 비트맵 인덱스 스캔을 수행하고 그 결과에 대해 department_id 조건을 필터링하는 방식을 사용한다.

결과적으로 복합 인덱스의 최종 cost는 8.17 단일 인덱스의 최종 cost는 9.51로 복합 인덱스의 성능이 더 좋았다. 테이블 데이터가 많아질수록 해당 쿼리의 성능은 복합 인덱스 쪽이 더욱 좋을 것이다.

3. 복합 인덱스로 단일 조건 조회

한 가지 더 알아야 하는 게 있다. 복합 인덱스를 생성할 때는 맨 앞에 오는 컬럼이 중요하다.

예를 들어

CREATE INDEX idx_department_role ON employees (department_id, role_id);

이렇게 인덱스를 생성했으면 department_id에 대해서는 추가적인 이점이 있다. department_id 컬럼에 단일 인덱스를 생성하는 것과 비슷한 효과를 얻을 수 있다.

SELECT * FROM employees WHERE department_id = 20

이런 쿼리를 할 때도 위의 복합 인덱스가 성능을 향상시킨다. 이건 복합 인덱스가 첫번째 컬럼을 데이터의 맨 앞에 저장하기 때문이다.

반면 두번째 컬럼인 role_id의 경우 단일 조건으로 필터링 할 경우 인덱스가 기여하지 못한다.

내용을 정리하면 테이블 조회는 여러 시나리오로 수행될 수 있는데 두 개 이상의 조건이 함께 필터링되는 패턴이 많이 쓰이는 경우엔 함께 쓰이는 조건을 조합해서 복합 인덱스 사용을 고려한다. 그리고 복합 인덱스 생성할 땐 더 많이 쓰이는 조건 컬럼을 첫번째 순서에 두는 게 좋다.

댓글 남기기