MySQL 인덱스 최적화 완벽 가이드: 쿼리 성능 10배 향상시키기
느린 쿼리를 빠르게 만드는 MySQL 인덱스 최적화 실전 가이드. 단일 인덱스, 복합 인덱스, 커버링 인덱스까지 실제 예제로 배웁니다.
럿지 AI 팀
4분 읽기
목차
MySQL 인덱스 완벽 가이드
인덱스란?
책의 색인처럼 데이터를 빠르게 찾기 위한 자료구조
**효과:** 쿼리 속도 10-100배 향상
1단계: 문제 확인
느린 쿼리 예제
``
sql
-- 회원 100만 명 중 이메일로 검색
SELECT * FROM members WHERE email = 'user@example.com';
-- 실행 시간: 3초
`
EXPLAIN으로 분석
`sql
EXPLAIN SELECT * FROM members WHERE email = 'user@example.com';
-- 결과:
-- type: ALL (풀 테이블 스캔!)
-- rows: 1000000 (100만 행 모두 읽음)
`
**문제:** 인덱스 없어서 전체 테이블 스캔
2단계: 단일 인덱스
인덱스 생성
`sql
CREATE INDEX idx_email ON members(email);
`
효과 확인
`sql
EXPLAIN SELECT * FROM members WHERE email = 'user@example.com';
-- 결과:
-- type: ref (인덱스 사용!)
-- rows: 1
`
**실행 시간:** 3초 → **0.01초** (300배 향상!)
3단계: 복합 인덱스
복합 쿼리
`sql
-- 상태와 날짜로 주문 검색
SELECT * FROM orders
WHERE status = 'PAID' AND order_date >= '2024-01-01';
-- 느림!
`
잘못된 인덱스
`sql
-- 각각 단일 인덱스 생성 (비효율)
CREATE INDEX idx_status ON orders(status);
CREATE INDEX idx_date ON orders(order_date);
`
**문제:** MySQL은 하나만 사용
올바른 복합 인덱스
`sql
CREATE INDEX idx_status_date ON orders(status, order_date);
`
컬럼 순서 중요!
**원칙:** 선택도가 높은 컬럼을 앞에
`sql
-- 좋음: status(5종류) → order_date(다양)
CREATE INDEX idx_status_date ON orders(status, order_date);
-- 나쁨: 순서 반대
CREATE INDEX idx_date_status ON orders(order_date, status);
`
**효과:**
- 좋은 순서: 0.05초
- 나쁜 순서: 0.5초
4단계: 커버링 인덱스
일반 쿼리
`sql
SELECT id, email, name FROM members WHERE email = 'user@example.com';
-- 과정:
-- 1. idx_email에서 id 찾기
-- 2. 테이블에서 name 가져오기 (추가 I/O)
`
커버링 인덱스
`sql
CREATE INDEX idx_email_name ON members(email, name);
-- 이제 인덱스만으로 모든 데이터 제공!
`
**효과:**
- Before: 0.01초
- After: **0.002초** (5배 향상)
5단계: WHERE 절 패턴별 인덱스
등호(=)
`sql
WHERE status = 'PAID'
-- 인덱스: CREATE INDEX idx_status ON orders(status);
`
범위(>, <, BETWEEN)
`sql
WHERE order_date >= '2024-01-01'
-- 인덱스: CREATE INDEX idx_date ON orders(order_date);
`
LIKE (앞부분 일치)
`sql
WHERE name LIKE '홍%' -- ✓ 인덱스 사용
WHERE name LIKE '%홍%' -- ✗ 인덱스 미사용
`
IN
`sql
WHERE status IN ('PAID', 'SHIPPED')
-- 인덱스: CREATE INDEX idx_status ON orders(status);
`
6단계: 인덱스 확인
현재 인덱스 보기
`sql
SHOW INDEX FROM orders;
`
실행 계획 분석
`sql
EXPLAIN SELECT * FROM orders
WHERE status = 'PAID' AND order_date >= '2024-01-01';
-- 확인 사항:
-- type: ref (좋음) vs ALL (나쁨)
-- key: 사용된 인덱스 이름
-- rows: 검사한 행 수 (적을수록 좋음)
`
7단계: 불필요한 인덱스 제거
중복 인덱스
`sql
-- 중복!
CREATE INDEX idx_email ON members(email);
CREATE INDEX idx_email_name ON members(email, name);
-- idx_email은 불필요 (idx_email_name이 커버)
DROP INDEX idx_email ON members;
`
사용 안 하는 인덱스
`sql
-- 사용 통계 확인 (MySQL 8.0+)
SELECT * FROM sys.schema_unused_indexes;
-- 사용 안 하는 인덱스 삭제
DROP INDEX idx_old ON members;
`
**이유:** 인덱스는 쓰기 성능 저하
실전 예제
Case 1: 주문 검색
`sql
-- 쿼리
SELECT order_id, total_amount
FROM orders
WHERE member_id = 123 AND status = 'PAID'
ORDER BY order_date DESC
LIMIT 10;
-- 최적 인덱스
CREATE INDEX idx_member_status_date
ON orders(member_id, status, order_date DESC);
-- 효과: 2초 → 0.01초
`
Case 2: 상품 검색
`sql
-- 쿼리
SELECT product_id, name, price
FROM products
WHERE category_id = 5 AND price BETWEEN 10000 AND 50000;
-- 최적 인덱스
CREATE INDEX idx_category_price
ON products(category_id, price);
-- 커버링 인덱스 (name 포함)
CREATE INDEX idx_category_price_name
ON products(category_id, price, name);
-- 효과: 1초 → 0.005초
`
주의사항
1. 인덱스 남발 금지
**문제:**
- 쓰기 성능 저하
- 스토리지 낭비
**원칙:**
자주 조회되는 WHERE/ORDER BY 컬럼만
2. 함수 사용 시 인덱스 무효화
`sql
-- ✗ 인덱스 사용 안 됨
WHERE YEAR(order_date) = 2024
-- ✓ 인덱스 사용됨
WHERE order_date >= '2024-01-01' AND order_date < '2025-01-01'
`
3. NULL 값
`sql
-- NULL 체크는 인덱스 사용 가능
WHERE email IS NOT NULL
`
성능 측정
Before
`sql
-- 인덱스 없음
SELECT * FROM orders WHERE member_id = 123;
-- 실행 시간: 5초
-- 검사 행: 1,000,000
`
After
`sql
-- 인덱스 있음
CREATE INDEX idx_member ON orders(member_id);
SELECT * FROM orders WHERE member_id = 123;
-- 실행 시간: 0.01초
-- 검사 행: 50
``**개선:** 500배!
더 배우기
김영한의 실전 데이터베이스
- 파티셔닝과 인덱스
- 대용량 데이터 최적화
- 실전 프로젝트
---
**태그**: #MySQL인덱스 #쿼리최적화 #성능튜닝 #복합인덱스 #튜토리얼
L
럿지 AI 팀
AI 기술과 비즈니스 혁신을 선도하는 럿지 AI의 콘텐츠 팀입니다.
관련 포스트
비즈니스
블랙프라이데이 무장애 성공: DB 최적화로 거래량 1000% 폭증 대응
올바른 DB 설계와 파티셔닝으로 블랙프라이데이 거래 폭증을 무장애로 처리하고 매출 500억을 달성한 커머스 기업 사례입니다.
•4분 읽기
뉴스
2025 데이터베이스 시장 전망: MySQL이 여전히 1위, 클라우드 DB 급성장
2025년 데이터베이스 시장 분석. MySQL 점유율 1위 유지, AWS RDS·Azure DB 등 클라우드 DB 시장 연 25% 성장.
•4분 읽기
튜토리얼
B2B SEO 완벽 가이드: 의사결정권자를 검색으로 확보하는 법
B2B 기업을 위한 SEO 전략. 영업 없이 리드를 자동으로 확보하는 검색 최적화 완벽 가이드입니다.
•1분 읽기