데이터베이스에서 인덱스는 검색 성능을 향상시키기 위한 자료구조이다. 인덱스는 책의 목차처럼, 원하는 데이터를 빠르게 찾기 위해 미리 정리해놓은 정보를 말한다. 특히 대량의 데이터 중에서 조건에 맞는 데이터를
빠르게 조회해야 할 때 인덱스가 큰 역할을 한다.
MySQL(InnoDB)에서 인덱스는 B+ Tree 구조로 되어있는데, 이 트리는 자동으로 데이터를 정렬된 순서로 저장하고 유지한다. 정렬된 자료구조는 다음과 같은 작업을 빠르게 동작할 수 있도록 해준다.
| 작업 유형 | 정렬이 중요한 이유 |
|---|---|
| WHERE age = 20 | 중간 지점부터 빠르게 탐색 사능하다 (Binary Search 처럼) |
| WHERE age BETWEEN 20 AND 30 | 범위 검색 시 리프 노드를 순차 탐색한다 |
| ORDER BY age | 이미 정렬되어 있어 별도의 정렬 연산이 필요 없다 |
| GROUP BY | 그룹이 붙어 있어서 정렬 없이 처리 가능하다 |
MySQL 8.0 부터는 명시적으로 인덱스의 오름차순/내림차순을 지정할 수 있다.
CREATE INDEX idx_age_asc ON users(age ASC);
CREATE INDEX idx_age_desc ON users(age DESC);
하지만 B+ Tree 자체는 양방향 순회가 가능하기 때문에 대부분의 경우 오름차순 인덱스 하나로도 내림차순 쿼리를 처리할 수 있다.
| 종류 | 설명 |
|---|---|
| 기본 인덱스, Primary Index | 기본 키에 자동으로 생성되는 인덱스 |
| 보조 인덱스, Secondary/Non-clustered Index | 기본 키 외의 컬럼에 사용자가 수동으로 생성하는 인덱스 |
| 유니크 인덱스, Unique Index | 중복을 허용하지 않는 인덱스 |
| 복합 인덱스, Composite Index | 여러 개의 컬럼을 묶어서 만든 인덱스 |
| 클러스터형 인덱스, Clustered Index | 데이터 자체가 인덱스 순서대로 저장되는 방식(MySQL InnoDB는 기본적으로 클러스터형 인덱스를 사용한다) |
| 비트맵 인덱스, Bitmap Index | 비트맵 형태로 인덱싱하는 인덱스(OLAP, 조건이 다양한 분석에 유리하다) |
| 전문검색 인덱스, Full Text Index | 텍스트 검색용 인덱스(LIKE, MATCH AGAINST 등) |
회원가입 시에 이메일 중복 검사가 필요하여 데이터베이스에 조회를 해야 할 때 아래와 같은 인덱스를 생성할 시 빠르게 조회할 수 있다.
-- 인덱스 생성
CREATE INDEX idx_user_email ON users (email);
-- 인덱스 보기
SHOW INDEX FROM users;
-- 인덱스 삭제
DROP INDEX idx_user_email ON users;
쿼리 성능을 분석할 때는 EXPLAIN 키워드를 사용하여 인덱스가 실제로 사용되었는지 확인해야 한다.
EXPLAIN
SELECT *
FROM users
FORCE INDEX (idx_user_email) -- row수가 적을 때는 강제적으로 인덱스를 사용하도록 설정
WHERE email = 'rlarlgus0206@naver.com';