쿼리 최적화(Query Optimization)는 SQL 쿼리가 최소한의 자원으로 빠르게 실행되도록 개선하는 기술이다. 데이터베이스 성능 문제의 90%는 잘못된 쿼리나 인덱스 부재에서 발생한다.
느린 쿼리 원인
sql
-- 나쁜 예: 인덱스를 사용하지 못하는 패턴
SELECT * FROM orders WHERE YEAR(created_at) = 2024; -- 함수 사용
SELECT * FROM users WHERE name LIKE '%김%'; -- 앞 와일드카드
SELECT * FROM products WHERE price + 100 > 500; -- 컬럼 연산
-- 좋은 예
SELECT * FROM orders WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31';
SELECT * FROM users WHERE name LIKE '김%'; -- 앞 고정
SELECT * FROM products WHERE price > 400;
핵심 최적화 기법
1. 적절한 인덱스 설계
sql
-- 복합 인덱스: 선택도 높은 컬럼을 앞에 배치
CREATE INDEX idx_orders ON orders (user_id, status, created_at);
-- 커버링 인덱스: SELECT 컬럼도 인덱스에 포함
CREATE INDEX idx_cover ON orders (user_id) INCLUDE (total, created_at);
2. N+1 문제 해결
sql
-- N+1 문제: 사용자마다 주문 조회 (1 + N 쿼리)
SELECT * FROM users;
-- 각 user에 대해: SELECT * FROM orders WHERE user_id = ?
-- 해결: JOIN으로 단일 쿼리
SELECT u.*, o.id, o.total
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
3. 페이지네이션 최적화
sql
-- 느린 방법: OFFSET이 클수록 느려짐 (O(n))
SELECT * FROM posts ORDER BY id DESC LIMIT 20 OFFSET 10000;
-- 빠른 방법: Keyset Pagination (O(log n))
SELECT * FROM posts WHERE id < :last_id ORDER BY id DESC LIMIT 20;
쿼리 최적화 체크리스트
| 항목 | 확인 |
|---|
| EXPLAIN으로 실행 계획 확인 | Full Scan 여부 |
| 인덱스 사용 여부 | Index Scan vs Seq Scan |
| 불필요한 컬럼 제거 | SELECT * 지양 |
| 서브쿼리 → JOIN 변환 | 성능 비교 후 적용 |
| 통계 최신화 | ANALYZE 실행 |
관련 개념