# INDEX 인덱스
인덱스란 무엇인가?
인덱스는 데이터베이스 테이블 검색의 성능을 향상시키기 위한 자료 구조이다.
특정 컬럼에 인덱스를 생성하면, 해당 컬럼의 데이터들은 정렬 후 별도의 메모리 공간에 데이터의 물리적 구조와 함께 저장된다.
이 과정을 통해 인덱스가 생성되고 WHERE 조건으로 조회 시 옵티마이저에서 판단하여 생성된 인덱스를 탈 수 있다.
흔히 책의 맨 앞 또는 맨 뒤에 위치한 색인과 동일한 역할을 한다.
일반적으로 SELECT(조회) 성능만 향상된다고 착각하는 경우가 있는데,
Update(수정), Delete(삭제) 성능도 향상된다.
Update, Delete도 해당 대상 조회 후 수행하는 것이니,,,
# 장점
인덱스의 가장 큰 특징은 데이터들이 정렬되어 있다는 점이다.
- WHERE
- 테이블에 등록된 데이터는 내부적으로 순서가 없이 저장된다.
- 즉, WHERE 조건으로 검색 시 검색 조건에 맞는지 Full Scan을 진행한다.
- 하지만, 인덱스가 있다면 인텍스 테이블에 이미 정렬이 되어 데이터들이 저장되어 있기에 빠르다.
- ORDER BY
- ORDER BY는 부하가 많이 걸리는 작업 중 하나이다.
- 인덱스를 사용하면 ORDER BY에 의한 정렬을 피할 수 있다.
- 왜? 이미 정렬 되어 있으니까...
- MIN & MAX
- 인덱스로 정렬되어 있다면 MIN, MAX는 별도 구성 없이, 정렬된 데이터의 시작 값과 끝 값이다.
## 단점
장점인 정렬 상태를 최신으로 유지하기 위한 오버헤드가 발생한다.
- DML에 취약
- INSERT, UPDATE, DELETE 쿼리 수행 시 데이터 값에 변동이 생겨, 다시 정렬해야 한다.
- 풀 스캔보다 무조건 좋지 않다.
- 전체 데이터 중 10 ~ 15% 이하의 데이터를 처리하는 경우에 인덱스는 효율적이다.
- 그 이상의 데이터를 처리할 땐 인덱스를 사용하지 않는 것이 효율적이다.
- 인덱스도 저장공간이 필요하다. 너무 많이 만들지 말자
- 인덱스를 관리하기 위해서는 데이터베이스의 약 10%에 해당하는 저장공간이 추가로 필요하다.
## 관리
인덱스는 항상 최신의 데이터를 정렬된 상태로 유지해야 한다.
그렇기에 인덱스가 적용된 컬럼에 INSERT, UPDATE, DELETE가 수행될 때마다 정렬을 위한 연산이 추가되어 오버헤드가 발생한다.
이러한 이유로 인덱스는 '삭제'라는 개념보다, '미사용'이라는 개념으로 작업을 수행한다.
- INSERT : 새로운 데이터에 대한 인덱스 추가
- DELETE : 삭제하는 데이터의 인덱스를 미사용 처리
- UPDATE : 기존 인덱스를 미사용 처리하고, 갱신된 데이터에 대해 인덱스를 추가한다.
인덱스를 사용하는 것도 중요하지만 생성된 인덱스를 관리하는 것도 중요하다.
사용하지 않는 인덱스는 바로바로 제거하는 것이 좋다.
## 인덱스 생성 전략
모든 컬럼에 인덱스가 적용된다면 무의미하다.
- PK
- WHERE 조건절에 자주 사용되는 컬럼
- 항상 EQUAL(=) 비교되는 컬럼
- 중복되는 데이터가 최소한인 컬럼(분포도가 좋은 컬럼)
- ORDER BY 정렬절에 자주 사용되는 컬럼
- JOIN 조건으로 자주 사용되는 컬럼
- INSERT, UPDATE, DELETE가 자주 발생하지 않는 컬럼
## 인덱스에 사용되는 자료 구조
인덱스는 여러 자료구조를 이용해서 구현할 수 있는데, 대표적으로 Hash Table과 B+Tree가 있다.
### Hash Table
해시 테이블은 Key - Value 형태의 자료구조이다.
key 값을 이용해 고유한 인덱스를 생성하여, 그 인덱스에 저장된 값을 꺼내는 구조이다.
그렇기에 해시 테이블 내의 데이터들은 정렬되어 있지 않다.
즉, Key를 통해 검색하는 EQUAL(=) 연산에만 특화되어 있다.
반대로 정렬되어 있지 않기에, 부등호 연산이 자주 사용되는 DB 인덱스에서는 적합하지 않다.
### B+Tree
자식 노드가 2개 이상인 B-Tree를 개선시킨 자료 구조이다.
B+Tree는 대부분의 DBMS에서 사용하고 있는 인덱스 자료구조이다.
Leaf Node만 인덱스(Key)와 데이터(Value)를 가지고 있고,
나머지 Root Node와 Branch Node에는 데이터를 위한 인덱스(Key)만 가지고 있는다.
각 Leaf Node들은 LinkedList로 연결되어 있고, 선형 시간이 소모되어 시간 효율이 올라간다.
Leaf Node를 제외하곤 데이터를 저장하지 않기에 메모리 확보가 가능하다.
B Tree와 유사하지만 B Tree는 모든 노드에 데이터가 있어 풀 스캔해야 한다.
## DDL
INDEX 조회
SHOW INDEX FROM tableName;
INDEX 생성
CREATE INDEX indexName ON tableName(column1);
CREATE UNIQUE INDEX indexName ON tableName(column1);
ALTER TABLE tableName ADD INDEX indexNAme (column1...);
INDEX 삭제
ALTER TABLE tableName DROP INDEX indexName;
참고
- https://www.youtube.com/watch?v=Le74ewlajxg
- https://rebro.kr/167
'Develope > Database' 카테고리의 다른 글
[JPA Test] JPA 연동 Test (0) | 2022.07.30 |
---|---|
[Spring-Data-JPA] Auditing - Entity 공통 요소 자동 맵핑하기 (0) | 2022.07.30 |
[DB] Database Partitioning - DB 파티셔닝 개념 (0) | 2021.01.31 |
[MySQL Explain] 쿼리의 실행 계획 살펴보기 (0) | 2021.01.28 |
[MyBatis] RDB MyBatis란? 기본 설정 및 동적 쿼리 (0) | 2020.03.17 |