목표

  • WHERE 절에서 범위 탐색 시에 인덱스 설계하는 방법을 이해한다.

상황

SELECT first_name, last_name, date_of_birth
  FROM employees
 WHERE date_of_birth >= '1971-01-01'
   AND date_of_birth <= '1971-01-09'
   AND subsidiary_id  = 27
  • 위와 같은 상황에 date_of_birthsubsidiary_id 의 인덱스 컬럼 순서를 어떻게 해야될지 알아보자.

date_of_birth, subsidiary_id 순으로 인덱스 설계할 경우

  • date_of_birth 기준으로 먼저 정렬되어 있다. 중간 노드만으로는 어느 리프 노드가 subsidiary_id가 27인 경우를 가지고 있는지 알 수 없다.
  • 쿼리에 date_of_birth의 범위 조건이 있으므로, 이를 기준으로 먼저 범위 탐색을 하게 된다. 범위에 속하는 리프 노드가 여러개 발생한다.
  • 이미 여러 개의 리프 노드를 스캔하게 되었으므로, subsidiary_id 컬럼은 무의미하게 된다. 즉, 인덱스를 타지 않는다.

subsidiary_id, date_of_birth 순으로 인덱스 설계한 경우

  • subsidiary_id으로 먼저 정렬되어 있다. 중간 노드만으로도 두 번째 리프 노드만 방문하면 된다는 사실을 알 수 있다.
  • subsidiary_id, date_of_birth 모두 인덱스를 탈 수 있다.

결론

  • 범위 조건이 있는 컬럼이 인덱스 컬럼 앞부분에 있으면, 인덱스 뒷 부분은 인덱스를 타지 못할 확률이 높다.
  • 그렇다고 equal 연산을 하는 컬럼이 앞에 있다고 인덱스를 타지는 못한다. 선택도(selectivity)가 높은 컬럼이면 범위 조건과 같은 상황이 발생할 것이다.

참고 자료