INNODB에는 INDEX 종류가 두 가지가 있다. 클러스터 인덱스와 보조 인덱스이다.
클러스터 인덱스
보조 인덱스
📌 인덱스가 너무 많으면 성능 저하 가능
• 인덱스는 조회 성능을 향상시키지만, 데이터 변경(INSERT, UPDATE, DELETE) 시 인덱스도 함께 갱신해야 하기 때문에 너무 많은 인덱스는 오히려 성능을 저하시킬 수 있음.
• 자주 조회하는 쿼리에 맞게 최소한의 인덱스만 유지하는 것이 중요.
✅ 해결책:
• EXPLAIN을 사용해 실제로 쿼리가 어떤 인덱스를 사용하고 있는지 확인하고 불필요한 인덱스는 제거
• 자주 사용되지 않는 인덱스는 삭제 (DROP INDEX index_name ON table_name;)
📌 기본 키를 AUTO_INCREMENT로 하면 삽입 성능이 향상됨.
• 기본 키는 클러스터 인덱스(Clustered Index) 역할을 하므로, 기본 키가 변경되면 데이터 정렬이 다시 이루어져 성능 저하 발생 가능
• 랜덤한 값(예: UUID)을 기본 키로 사용하면 삽입 성능이 저하될 수 있음 (데이터 정렬 필요)
✅ 해결책
CREATE TABLE employees (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
age INT
) ENGINE=InnoDB;
• 연속적인 값(AUTO_INCREMENT)을 사용하면 데이터 정렬이 효율적
• UUID 같은 랜덤 값이 필요하다면 보조 인덱스로 관리
📌 여러 개의 단일 인덱스보다는 다중 컬럼 인덱스를 고려
• WHERE 절에서 여러 컬럼을 함께 사용하는 경우 다중 컬럼 인덱스를 사용하는 것이 유리함.
• 왼쪽에서 오른쪽 방향으로 정렬된 인덱스 순서에 맞춰 조회할 때만 최적화됨 (Leftmost Prefix Rule)
✅ 해결책:
CREATE INDEX idx_employee_name_age ON employees(name, age);
• WHERE name = 'Alice' AND age = 30 → 인덱스 사용 가능
• WHERE age = 30 → 인덱스 사용 불가능 (name 먼저 조회해야 함)
📌 이 경우라면 name, age 대신 age, name 순서로 변경해야 함!
📌 불필요하게 많은 컬럼을 인덱스에 포함하면 인덱스 크기가 커지고 성능이 저하됨.
• 인덱스에 포함된 컬럼이 많으면 데이터를 읽고 정렬하는 비용 증가
• 자주 사용하는 컬럼만 포함하도록 인덱스를 최소화
✅ 해결책:
• 조회 빈도가 높은 컬럼만 포함
• SELECT * 대신 실제로 필요한 컬럼만 조회
📌 인덱스만으로 데이터를 조회할 수 있다면 성능 향상 가능
• 일반적으로 보조 인덱스는 기본 키를 통해 실제 데이터를 추가 조회(Index Lookup)해야 하지만,
인덱스에 필요한 모든 컬럼이 포함되면 데이터 조회 없이 인덱스만으로 처리 가능 → 성능 향상!
✅ 해결책:
CREATE INDEX idx_covering ON employees(name, age);
SELECT name, age FROM employees WHERE name = 'Alice';
• name, age가 인덱스에 포함되어 있기 때문에 실제 테이블 조회 없이 인덱스만으로 결과 반환 가능
📌 LIKE 검색 시 인덱스 사용을 고려해야 함.
• LIKE '%keyword%' → 인덱스 사용 불가능
• LIKE 'keyword%' → 인덱스 사용 가능
✅ 해결책:
CREATE INDEX idx_name ON employees(name);
SELECT * FROM employees WHERE name LIKE 'A%'; -- ✅ 인덱스 사용 가능
SELECT * FROM employees WHERE name LIKE '%A%'; -- ❌ 인덱스 사용 불가능
인덱스를 활용하려면 접두어(prefix) 매칭을 사용해야 함!
📌 만약 전체 문자열 검색이 필요하다면?
• FULLTEXT INDEX 사용 (단, MyISAM 또는 InnoDB에서 지원)
📌 쿼리가 실제로 어떤 인덱스를 사용하고 있는지 확인하는 것이 중요
• EXPLAIN을 사용하면 쿼리 실행 계획을 확인할 수 있음
EXPLAIN SELECT * FROM employees WHERE name = 'Alice';
• possible_keys: 사용 가능한 인덱스
• key: 실제 사용된 인덱스
• rows: 조회 예상 행 수 (낮을수록 좋음)
✅ 해결책:
• key 값이 NULL이면 → 인덱스가 사용되지 않음 → 인덱스 추가 고려
• rows 값이 크면 → 인덱스 성능이 낮음 → 다중 컬럼 인덱스 또는 인덱스 재구성 고려
인덱스 설정된 컬럼 하나만 있는 경우
해당 컬럼 INDEX를 탄다.
인덱스 설정된 컬럼 하나, 인덱스 없는 컬럼 하나 있는 경우
인덱스 설정된 컬럼의 INDEX를 탄다.
각각 인덱스 설정된 컬럼이 두개 이상인 경우
DB 엔진이 최적화 알고리즘을 통해 제일 적합한 INDEX를 탄다.
복합 인덱스(두 컬럼에 동시에 인덱스가 설정됨)인 경우
두 컬럼 모두 and 조건으로 조회를 해야 INDEX를 탄다.