1. 인덱스란?
- **인덱스(Index)**는 데이터베이스에서 원하는 데이터를 빠르게 찾기 위해 사용하는 자료구조
- 책의 "색인"처럼 작동하며, 검색 속도를 획기적으로 향상시킬 수 있음
- 기본적으로 springboot에서 JPA로 자동으로 인덱스가 생성되는 것은 BTREE 인덱스를 따름
✅ 인덱스의 장점
- 빠른 검색 속도
- 정렬/필터링 최적화
- 조인 성능 향상
❗️단점
- 인덱스를 많이 만들수록 쓰기(INSERT/UPDATE) 성능 저하
- 디스크 공간 추가 사용
2. B-Tree 인덱스와 조회 방식 비교

📌 인덱스가 없는 경우 (Full Table Scan)
- 데이터를 맨 앞부터 끝까지 하나씩 비교하며 검색
- 시간 복잡도: O(n)
📌 인덱스가 있는 경우 (B-Tree)
- MySQL은 기본적으로 B-Tree 인덱스를 사용
- 이진 탐색 구조로 빠르게 원하는 값을 찾아감
- 시간 복잡도: O(log n)
- 위의 그림에서 8이라는 데이터를 찾기 위해서 7< 8 < 15, 8 < 9 로 2번만 판단하면 됨.
-> 모든 열을 다 조회하는 것이 아닌, 위의 예시에서 모든 데이터에 대해 최대 2번만에 접근 가능
예를 들어, 100만 명 중 한 명의 이메일을 검색할 때:
- ❌ 인덱스 없음: 100만 명 전부 비교
- ✅ 인덱스 있음: 몇 번만 비교해도 찾음 (로그 탐색)
3. 인덱스를 사용할 수 없는 경우: LIKE '%abc%'
📌 이런 쿼리는 인덱스를 사용할 수 없음
SELECT * FROM users WHERE username LIKE '%hong';
- %가 앞에 있으면 MySQL이 B-Tree 인덱스를 사용할 수 없음
- 이유: 트리의 시작 지점을 알 수 없기 때문
✅ 인덱스를 사용하려면
SELECT * FROM users WHERE username LIKE 'hong%'; # ✅ 사용 가능
🔁 해결 방법
- 중간 검색이 필요하다면 Full-Text Index를 고려
4. MySQL에서 인덱스 설정 & 사용 확인 방법
✅ 인덱스 생성
CREATE INDEX idx_users_email ON users(email);
✅ 인덱스 확인
SHOW INDEX FROM users;
| Key_name | Column_name | Non_unique(중복이 허용되는가?) | 설명 |
| PRIMARY | user_id | 0(불가) | 기본키(PK) |
| idx_users_email | 1(가능) | 일반 인덱스 (중복 허용) |
✅ 인덱스 사용 확인 (EXPLAIN)
EXPLAIN SELECT * FROM users WHERE email = 'abc@example.com';
| key | type | rows | Extra |
| idx_users_email | const | 1 | Using index |
- key에 인덱스 이름이 보이면 실제 사용 중!!!
5. Primary 키 & Foreign 키의 자동 인덱스 생성
| 키 종류 | 인덱스 생성 여부 | Non_unique |
| @Id (기본키) | ✅ 자동 생성됨 | 0 (UNIQUE) |
| @ManyToOne (외래키) | ✅ 자동 생성됨 | 0 또는 1 |
📌 외래키도 JPA가 JOIN 성능 향상을 위해 자동으로 인덱스를 생성
6. Spring Boot 엔티티에서 인덱스 자동 생성 설정
✅ 방법 1: @Column(unique = true)
@Column(unique = true) private String email;
→ Hibernate가 자동으로 UNIQUE 인덱스 생성
✅ 방법 2: @Table(uniqueConstraints = {...})
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = {"club_id", "user_id"}) })
→ 복합 유니크 인덱스 생성 (예: 동일 동아리에 중복 가입 방지)
⚠️ 주의: 둘 다 동시에 쓰면 중복 인덱스가 생성됨!! -> 불필요(성능 저하)
- @Column(unique = true) 또는 @UniqueConstraint 중 하나만 사용 권장
7. 실전 예시: 이메일로 사용자 조회
Optional<User> findByEmail(String email);
- JPA → Hibernate → SQL 변환:
SELECT * FROM users WHERE email = 'abc@example.com';
- email 컬럼에 인덱스가 있다면 빠르게 검색됨
- EXPLAIN으로 인덱스 사용 여부 확인 가능
- 이메일 인증으로 통해 아이디나 비밀번호 찾기 기능을 지원하는 로그인 기능의 경우, 이메일 인덱스를 활용해 조회 속도를 높일 수 있음