인덱스가 많으면 생기는 문제
- DML 성능 저하 ( → TPS 증가 )
- 데이터베이스 사이즈 증가 ( → 디스크 공간 낭비 )
- 데이터베이스 관리 및 운영 비용 상승
※ 인덱스 추가는 시스템에 부하를 주고, 인덱스 변경은 운영 리스크가 크다. 그러므로, 시스템 개발단계에서 인덱스를 최적으로 설계하는 것이 무엇보다 중요하다.
인덱스 구성 컬럼 선정 기준
- 조건절에 항상 사용하거나, 자주 사용하는 컬럼을 선정한다.
- '=' 조건으로 자주 조회되는 컬럼을 앞쪽에 둔다.
스캔 효율성 이외의 판단 기준
- ⭐수행 빈도
- 수행 빈도가 높은 SQL의 경우, NL 조인 inner 쪽 인덱스는 '=' 조건 컬럼을 선두에 두는 것이 중요
- 업무상 중요도
- 클러스터링 팩터
- 데이터량
- DML 부하 (= 기존 인덱스 개수, 초당 DML 발생량, 자주 갱신하는 컬럼 포함 여부 등)
- 저장 공간
- 인덱스 관리 비용 등
전략적 설계
예를 들어, 10개의 액세스 경로가 있는 경우 최적을 달성해야 할 가장 핵심적인 액세스 경로 한두 개를 전략적으로 선택해서 최적 인덱스를 설계하고, 나머지 액세스 경로는 약간의 비효율이 있더라도 목표 성능을 만족하는 수준으로 인덱스를 구성할 수 있어야 한다.
⇒ 전략적 판단 근거가 있어야 한다.
소트 연산 생략을 위한 컬럼 추가
- 인덱스를 ORDER BY 순서대로 구성
- '=' 조건절 컬럼은 ORDER BY 절에 없더라도 인덱스 구성에 포함할 수 있다.
- '='이 아닌 조건절 컬럼들은 반드시 ORDER BY 컬럼보다 뒤쪽에 두어야 소트 연산을 생략할 수 있다.
⭐ I/O를 최소화 하면서 소트 연산을 생략하는 공식
- '=' 연산자로 사용한 조건절 컬럼 선정
- ORDER BY 절에 기술한 컬럼 추가
- '=' 연산자가 아닌 조건절 컬럼은 데이터 분포를 고려해 추가 여부 결정
IN 조건절과 소트 연산
select 고객번호, 고객명, 거주지역, 혈액형, 연령
from 고객
where 거주지역 = '서울'
and 혈액형 in ('A', 'O')
order by 연령
- 소트 연산을 생략하려면 IN 조건절이 IN-List Iterator 방식으로 풀려선 안된다.
⇒ IN 조건절을 인덱스 액세스 조건이 아닌 필터 조건으로 사용해야 한다.
- 인덱스를 [ 거주지역 + 연령 + 혈액형 ] 순으로 구성해야 한다.
결합 인덱스 선택도
- 선택도(Selectivity) : 전체 레코드 중 조건절에 의해 선택되는 레코드 비율
- 인덱스 선택도 : 인덱스 컬럼을 모두 '='로 조회할 때 평균적으로 선택되는 비율
- 선택도가 높은 ( 카디널리티가 높은 ) 인덱스는 생성해봐야 효능가치가 별로 없다.
→ 테이블 액세스가 많이 발생하기 때문
- 컬럼 간 순서를 결정할 때는 각 컬럼의 선택도 보다 필수 조건 여부, 연산자 형태가 더 중요한 판단 기준이다.