Index
란 DB의 테이블에 대한 검색 속도를 향상 시켜주는 자료구조.풀 스캔(Full Scan)
또는 테이블 스캔(Table Scan)
이라고 한다.INSERT : 새로운 데이터에 대한 인덱스를 추가
DELETE : 삭제하는 데이터의 인덱스를 사용하지 않는다는 작업 수행
UPDATE : 기존의 인덱스를 사용하지 않음 처리, 갱신된 데이터에 대한 인덱스 추가
이처럼 인덱스의 수정도 추가적으로 필요하기 때문에 데이터의 수정이 잦은 경우 성능이 낮아진다. 또 데이터의 인덱스를 제거하는 것이 아니라 '사용하지 않음'으로 처리하고 남겨두기 때문에 수정 작업이 많은 경우 실제 데이터에 비해 인덱스가 과도하게 커지는 문제점이 발생할 수 있다. 별도의 메모리 공간에 저장되기 때문에 추가 저장 공간도 많이 필요하게 된다.
또한 인덱스는 전체 데이터의 10 ~ 15% 이상의 데이터를 처리하거나, 데이터의 형식에 따라 오히려 성능이 낮아질 수 있다.예를 들어 나이나 성별과 같이 값의 range가 적은 컬럼인 경우, 인덱스를 읽고 나서 다시 많은 데이터를 조회해야 하기 때문에 비효율적이다.
앞서 설명한 단점으로 인해 마구잡이식의 인덱스 설정보다는 퍼포먼스를 극대화할 수 있는 설정 기준이 필요하다.
카디널리티(Cardinality)
가 높은 컬럼
카디널리티가 높다 = 한 컬럼이 가지고 있는 값의 중복도가 낮음(값들이 대부분 다른 값을 가짐)
카디널리티가 낮다 = 한 컬럼이 갖고 있는 값의 중복도가 높음(값들이 거의 같은 값을 가짐)
선택도(Selectivity)
가 낮은 컬럼
선택도가 5 ~ 10%가 적정
선택도가 높다 = 한 컬럼이 가지고 있는 값 하나로 여러 row가 찾아진다
선택도가 낮다 = 한 컬럼이 가지고 있는 값 하나로 적은 row가 찾아진다
선택도 계산법
(= 컬럼의 특정 값의 row 수 / 테이블의 총 row 수 * 100)
ex) 10개의 데이터에서 고유한 학번(grade) 컬럼, 2명씩 같은 이름(name) 컬럼, 5명씩 같은 나이(age) 컬럼인 경우
① 학번(grade) 컬럼 선택도: 1 / 10 = 10%
② 이름(name) 컬럼 선택도: 2 / 10 = 20%
③ 나이(age) 컬럼 선택도: 5 / 10 = 50%
활용도
가 높은 컬럼
WHERE, ORDER BY, JOIN에 자주 사용되는 컬럼에 사용
수정빈도
가 낮은 컬럼
1. LIKE 연산자를 사용한 경우
- LIKE 연산자를 이용하여 검색할 경우 %를 뒤에 넣어 사용
- 가능하면 INSTR을 사용하는 것도 괜찮다.
SELECT name FROM table WHERE name LIKE '%n%'
-> SELECT name FROM table WHERE name LIKE 'n%'
-> SELECT name FROM table WHERE INSTR(name, 'n') > 0
2. 수식이나 함수 등으로 인덱스 컬럼을 변형하였을 경우
3. 내부적으로 데이터 형 변환이 일어난 경우
SELECT name FROM table WHERE name = '20200101'
-> SELECT name FROM table WHERE name = TO_DATE('20200101', 'YYYYMMDD')
4. 조건절에 NULL 또는 NOT NULL을 사용하는 경우
- 인덱스를 구성한 컬럼값이 전부 NULL이라면 인덱스는 이런 값을 저장하지 않음
5. 부정형으로 조건을 사용한 경우
SELECT name FROM table WHERE number != 10
-> SELECT name FROM table WHERE number < 10 AND number > 10
-> SELECT name FROM table WHERE NOT EXISTS (SELECT name FROM table WHERE number = 10)
6. OR 조건 사용
- UNION 절 활용
SELECT t1.name FROM table t1, table2 t2 WHERE t1.name = t2.name OR t1.age = t2.age
-> SELECT t1.name FROM table t1, table2 t2 WHERE t1.name = t2.name
UNION ALL
SELECT t1.name FROM table t1, table2 t2 WHERE t1.age = t2.age
결합인덱스
란 복수의 컬럼으로 구성된 인덱스
//결합 인덱스 생성 구문 예시
CREATE INDEX idx_composite_index
ON Test(id, name, date)