1. 인덱스
- 데이터베이스에서 인덱스는 마치 책의 목차와 같다.
- 방대한 양의 데이터 속에서 원하는 정보를 빠르게 찾아낼 수 있도록 돕는 특별한 데이터 구조
- 인덱스는 테이블 데이터를 효율적으로 정렬해 저장함으로써, 대규모 데이터베이스에서도 뛰어난 조회 성능을 제공한다.
1-1. B-Tree구조
- 키(Key)와 포인터(Pointer)구조의 노드
- 자기균형 트리 : 루트노드와 리프노드를 재정렬함. - 쓰기 작업 성능 저하와 연관
- 데이터 검색 시, 루트 노드에서 시작하여 리프 노드까지 이동하며 원하는 데이터를 빠르게 찾아낸다.
- 트리의 높이가 낮게 유지되므로 대규모 데이터셋에서도 균일한 검색 성능을 제공한다.
1-2. 인덱스가 성능에 미치는 영향
- 장점
- 검색속도 향상
- 서버 부하 감소
- 대용량 데이터 지원
- 단점
- 추가 저장공간 필요 : 별도의 저장공간을 필요로하는 인덱스는 디스크 공간 사용량을 늘린다. 적은양의 인덱스로 최대한의 성능을 뽑아내야함.
- 쓰기 작업 성능 저하 : Insert, Delete, Update 시마다 인덱스도 함께 변경됨.
- 데이터베이스 옵티마이저가 어떤 인덱스를 사용할지 결정하는 데 더 많은 시간을 소요하게 만들거나, 비효율적인 인덱스를 선택하게 만들 수도 있다.
- 쿼리 최적화 방해
1-3. 인덱스 유형
- 기본인덱스
- PK : 각 행을 고유하게 식별하기 위해 사용되는 특별한 인덱스
- Unique Index : NULL 값을 허용
- 복합인덱스
- 단, FK는 인덱스가 아니다. (규칙이지, 성능 구조(Index)가 아님.) 자식 테이블 FK 컬럼이 인덱스 없으면 자식 테이블 풀스캔이 뜨면서 성능이 크게 박살남
1-4. 인덱스 설계 주의사항
- 다른컬럼으로 추론 가능한 값은 인덱스 설계하지 않도록한다.
- 인덱스의 과도한 생성은 지양한다.
- 인덱스의 크기를 관리해야한다.
- 부분 인덱스(Partial Index/Filtered Index)
- 커버링 인덱스(Covering Index)
- 카디널리티(Cardinality) 고려 : 카디널리티는 특정 컬럼에서 고유한 값의 개수를 나타냄.
- 카디널리티가 높은 컬럼 : id, email, 주민번호
- 카디널리티가 낮은 컬럼 : 고유한 값이 적은 컬럼 성별(남,여) , 여부(y,n) 등
- 카디널리티가 낮으면 단독인덱스 없이 추론하는게 좋다.
- 카디널리티가 높은 컬럼을 인덱스의 가장 앞쪽에 배치하는 것이 일반적인 권장 사항
2. 트랜잭션 전파 옵션
| 옵션 |
핵심 동작 |
주 사용 사례 |
| REQUIRED |
있으면 참여, 없으면 생성. |
(기본값) 데이터의 생성/수정/삭제 등 원자성이 보장되어야 하는 모든 일반적인 작업. |
| REQUIRES_NEW |
항상 새로운 트랜잭션을 생성. |
메인 로직의 성공/실패와 무관하게 반드시 기록되어야 하는 로그, 이력, 알림 등. |
| NESTED |
부모 트랜잭션 내에 중첩 트랜잭션(SAVEPOINT) 생성. |
하나의 큰 작업 내에서 부분적인 실패를 롤백하고 싶을 때. (예: 쿠폰 적용 실패) |
| SUPPORTS |
있으면 참여, 없으면 트랜잭션 없이 실행. |
트랜잭션이 필수는 아니지만, 필요시 참여하면 좋은 단순 조회(Read-Only) 작업. |
3. 롤백 전략과 외부 API 연동
3-1. Spring의 기본 롤백 규칙
- 언체크 예외 (Unchecked Exception) : RuntimeException을 상속 함
- 트랜잭션을 자동으로 롤백합니다. ✅
- 예측 불가한 시스템적 결함으로 간주
- 체크 예외 (Checked Exception) : RuntimeException을 상속하지 않음
- 트랜잭션을 롤백하지 않고 커밋합니다. ❌
- 예측가능하고 복구가능한 오류로 인식