인덱스는 테이블의 key 역할을 하는 컬럼의 데이터와 물리적 메모리의 저장 공간을 매핑해놓은 자료구조이다. 보통 트리구조로 되어있는 B-Tree 인덱스를 많이 사용한다. DB에서 가장 많은 자원이 소모되는 동작인 물리적 데이터 조회를 줄이기 위해 사용된다. 인덱스를 통해 빠르게 데이터의 위치를 찾고, 이후 key 컬럼 외의 다른 데이터를 가져오기 위해 테이블에는 한번만 액세스 하는 방식이다.
인덱스 스캔
인덱스 또한 물리적 데이터에 저장되어 있기 때문에 인덱스를 효율적으로 스캔하는 것 또한 중요하다. SQL에 조건이 어떻게 걸려있는지에 따라 인덱스 구성이 달라진다.
드라이빙 조건과 체크 조건
인덱스를 가장 효율적으로 사용하는 방법은 인덱스 스캔 시 조건에 해당하지 않는 데이터를 읽지 않는 것이다. 즉 Where 절의 조건으로 필요한 데이터를 걸러낼 때, 최종적으로 필요한 데이터 외에 다른 데이터를 읽지 않아야 한다. 이러한 관점에서 조건절의 조건들 중 스캔 시 비효율이 없는 조건을 드라이빙 조건이라고 하고, 그렇지 못한 경우 체크 조건이라고 한다. 어떤 조건이 드라이빙 조건이고, 체크 조건인지는 인덱스가 어떤 순서로 구성되어있는지에 따라 달라진다.
예를 들어 인덱스를 구성하는 첫번째 컬럼이 날짜 컬럼이고, where 절에 이에 대한 BETWEEN 조건이 걸려있다면, 이후에 오는 조건은 모두 체크 조건이 된다. 날짜 범위로 먼저 인덱스를 스캔해서 범위를 좁히지만 두번째, 세번째 조건에 해당하지 않는 데이터 또한 포함되게 되기 때문이다. 이러한 원리로 ‘=’와 In 조건을 제외한 모든 연산이 사용되는 컬럼 이후에 인덱스가 위치하는 모든 조건은 체크 조건이 된다.
즉 인덱스 선두 컬럼은 In이나 = 조건으로 사용되는 컬럼을 지정하는 게 무조건 유리하다. 그렇지 않다면 인덱스 뒤쪽으로 두어야 비효율이 줄어든다.
카디널리티
분포도 또한 중요한 요소이다. 카디널리티가 높을수록 (중복 값이 적을수록) 인덱스로 사용했을 때 효율이 높다. ex) 주문번호
결합 인덱스 우선순위 결정
사용 빈도 또한 중요하다. 여러 SQL에서 조건으로 사용되는 경우에 인덱스로 만들어야 효용이 높다.