SQL 쿼리 최적화, 인덱스 전략 및 EXPLAIN 분석을 마스터하여 데이터베이스 성능을 획기적으로 향상시키고 느린 쿼리를 제거합니다. 느린 쿼리 디버깅, 데이터베이스 스키마 설계 또는 애플리케이션 성능 최적화 시 사용하세요.
View on GitHubicartsh/icartsh_plugin
icartsh-plugin
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/icartsh/icartsh_plugin/blob/main/icartsh-plugin/skills/sql-optimization-patterns/SKILL.md -a claude-code --skill sql-optimization-patternsInstallation paths:
.claude/skills/sql-optimization-patterns/# SQL Optimization Patterns
체계적인 최적화, 올바른 인덱싱 및 쿼리 실행 계획 분석을 통해 느린 데이터베이스 쿼리를 번개처럼 빠른 작업으로 변환하세요.
## 적용 시기
- 느리게 실행되는 쿼리 디버깅
- 성능이 뛰어난 데이터베이스 스키마 설계
- 애플리케이션 응답 시간 최적화
- 데이터베이스 부하 및 비용 절감
- 데이터 증가에 따른 확장성 개선
- EXPLAIN 쿼리 실행 계획 분석
- 효율적인 인덱스 구현
- N+1 쿼리 문제 해결
## 핵심 개념 (Core Concepts)
### 1. 쿼리 실행 계획 (EXPLAIN)
EXPLAIN 출력을 이해하는 것은 최적화의 기본입니다.
**PostgreSQL EXPLAIN:**
```sql
-- 기본 실행 계획 확인
EXPLAIN SELECT * FROM users WHERE email = 'user@example.com';
-- 실제 실행 통계 포함
EXPLAIN ANALYZE
SELECT * FROM users WHERE email = 'user@example.com';
-- 더 많은 세부 정보를 포함한 상세 출력
EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT u.*, o.order_total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.created_at > NOW() - INTERVAL '30 days';
```
**주의 깊게 봐야 할 주요 지표:**
- **Seq Scan**: 전체 테이블 스캔 (대용량 테이블에서는 대개 느림)
- **Index Scan**: 인덱스 사용 (좋음)
- **Index Only Scan**: 테이블 접근 없이 인덱스만 사용 (가장 좋음)
- **Nested Loop**: 조인 방식 (작은 데이터셋에는 괜찮음)
- **Hash Join**: 조인 방식 (큰 데이터셋에 좋음)
- **Merge Join**: 조인 방식 (정렬된 데이터에 좋음)
- **Cost**: 추정된 쿼리 비용 (낮을수록 좋음)
- **Rows**: 추정된 반환 행 수
- **Actual Time**: 실제 실행 시간
### 2. 인덱스 전략 (Index Strategies)
인덱스는 가장 강력한 최적화 도구입니다.
**인덱스 유형:**
- **B-Tree**: 기본값, 등호(=) 및 범위 쿼리에 좋음
- **Hash**: 등호(=) 비교에만 사용
- **GIN**: 전체 텍스트 검색, 배열 쿼리, JSONB
- **GiST**: 기하학적 데이터, 전체 텍스트 검색
- **BRIN**: 데이터 간 상관관계가 있는 매우 큰 테이블을 위한 블록 범위 인덱스
```sql
-- 표준 B-Tree 인덱스
CREATE INDEX idx_users_email ON users(email);
-- 복합 인덱스 (순서가 중요합니다!)
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
-- 부분 인덱스 (행의 일부만 인덱싱)
CREATE INDEX idx_active_users ON users(email)
WHERE status = 'active';
-- 표현식 인덱스 (함수 기반 인덱스)
CREATE INDEX idx_users_lower_email ON users(LOWER(email));
-- 커버링 인덱스 (추가 컬럼 포함)
CREATE INDEX idx_users_email_covering ON users(email)
INCLUDE (name, created_at);
-- 전체 텍스트 검색 인덱스
CREATE INDEX idx_posts_search ON posts
USING GIN(to_tsvector('english', title || ' ' || body));
-- JSONB 인덱스
CREATE INDEX idx_metadata ON events USING GIN(metadata);
```
### 3. 쿼리 최적화 패턴
**SELECT * 피하기:**
```sq