본문 바로가기
DB

쿼리 속도가 100배 빨라진다? 실행 계획으로 파악하는 실전 SQL 튜닝

by 공부 안하고 싶은 사람 2026. 3. 31.
반응형
Database Performance Tuning

느린 쿼리와의 전쟁,
실행 계획(Explain)으로 끝내기

 

안녕하세요, code-resting입니다. 서비스가 커질수록 데이터베이스는 무거워지고, 어제까지 빨랐던 쿼리가 오늘 갑자기 느려지곤 합니다. 이때 무작정 인덱스를 거는 것은 해결책이 아닙니다. DB 옵티마이저가 어떤 경로로 데이터를 찾는지를 이해해야 하죠. 오늘은 실행 계획을 읽는 법과 성능을 비약적으로 높이는 튜닝 포인트를 짚어보겠습니다.

1. 실행 계획(EXPLAIN) 분석하기

쿼리 앞에 EXPLAIN 키워드만 붙이면 DB가 어떻게 데이터를 가져올지 미리 보여줍니다. 여기서 가장 먼저 확인해야 할 컬럼은 'type'입니다.

⚠️ 반드시 피해야 할 'type':

  • ALL (Full Table Scan): 인덱스를 타지 못하고 처음부터 끝까지 다 읽는 최악의 상태.
  • index: 인덱스 전체를 스캔하는 경우. Full Scan보다는 낫지만 데이터가 많으면 위험함.

✅ 지향해야 할 'type':

  • const / eq_ref: 고유 인덱스(PK 등)를 사용하여 단 1건만 찾는 최상의 상태.
  • ref / range: 특정 범위를 인덱스로 빠르게 찾는 상태.

2. 필살기: 커버링 인덱스(Covering Index)

인덱스를 탔는데도 느리다면 '데이터 페이지 접근(Random I/O)' 비용 때문일 수 있습니다. 인덱스에 검색에 필요한 모든 컬럼을 넣어두면, 실제 테이블에 접근하지 않고 인덱스만 읽고 쿼리를 끝낼 수 있습니다.

-- EXPLAIN 결과의 'Extra' 항목에 "Using index"가 뜬다면 커버링 인덱스가 적용된 것!
SELECT user_id, email FROM users WHERE user_id > 1000;
-- (user_id와 email이 복합 인덱스로 잡혀 있을 경우)

3. 복합 인덱스 구성의 황금률

인덱스 컬럼의 순서는 성능에 결정적인 영향을 미칩니다. 카디널리티(Cardinality)가 높은 컬럼을 앞에 두는 것이 유리합니다.

  • 카디널리티가 높다: 중복도가 낮고 값이 유니크하다 (예: 주민번호, ID)
  • 카디널리티가 낮다: 중복도가 높다 (예: 성별, 진행 상태)

순서: [ID] -> [날짜] -> [성별] (O) / [성별] -> [날짜] -> [ID] (X)

4. 인덱스를 죽이는 쿼리 작성 습관

아무리 인덱스를 잘 걸어도 쿼리를 잘못 짜면 인덱스를 타지 못합니다.

  • 컬럼 가공: WHERE DATE_FORMAT(reg_date) = '...' (인덱스 파괴)
  • 암시적 형변환: 숫자형 컬럼을 문자열로 조회 WHERE id = '1'
  • OR 연산자 남용: 복합 인덱스 구조에서는 OR보다 UNION ALL이 빠를 수 있습니다.

💡 마무리하며

DB 튜닝의 시작과 끝은 '실행 계획 확인'입니다. 코드를 배포하기 전, 슬로우 쿼리가 의심되는 부분에 EXPLAIN을 돌려보는 습관을 들이세요. 2026년 백엔드 개발자에게 SQL 튜닝은 단순한 스킬이 아니라, 서비스의 수명을 연장하는 예술입니다.

© 2026 code-resting. All rights reserved.

728x90
반응형

댓글