MySQL slow query 가이드: 쿼리가 느릴 때 어디부터 봐야 할까
DB

MySQL slow query 가이드: 쿼리가 느릴 때 어디부터 봐야 할까


MySQL을 운영하다 보면 가장 자주 만나는 문제 중 하나가 slow query입니다. 평소에는 괜찮던 API가 갑자기 느려지거나, 특정 화면만 유독 오래 걸릴 때 실제 원인을 따라가 보면 결국 느린 SQL 하나가 병목인 경우가 많습니다.

이 글에서는 아래 내용을 정리합니다.

  • MySQL 쿼리가 느릴 때 어디부터 확인할지
  • 인덱스와 실행 계획을 어떻게 봐야 할지
  • 정렬, 풀스캔, 조인에서 자주 생기는 문제

핵심은 slow query는 SQL 문장 하나만 보는 것이 아니라, 실행 계획과 데이터 접근 방식까지 함께 봐야 풀린다는 점입니다.

slow query는 왜 생길까

대표적인 원인은 아래와 같습니다.

  • 인덱스를 타지 못하는 조건
  • 너무 많은 행을 읽는 풀스캔
  • 큰 정렬이나 임시 테이블
  • 비효율적인 조인 순서
  • 반환 row 수가 과도한 쿼리

즉, “쿼리가 느리다”는 현상 뒤에는 실제로는 여러 종류의 병목이 숨어 있습니다.

먼저 무엇을 봐야 할까

입문 단계에서는 아래 순서가 가장 실용적입니다.

  1. 어떤 쿼리가 느린지 찾기
  2. EXPLAIN으로 실행 계획 보기
  3. 인덱스 사용 여부 확인
  4. 읽는 row 수가 비정상적으로 많은지 보기
  5. 정렬과 조인 비용 확인

즉, 감으로 SQL을 고치기보다 실제 실행 방식부터 확인하는 것이 중요합니다.

EXPLAIN에서 특히 봐야 하는 것

EXPLAIN을 보면 초보자도 아래 항목부터 보면 도움이 됩니다.

  • type
  • key
  • rows
  • Extra

특히:

  • ALL: 풀스캔 가능성
  • key = NULL: 인덱스 미사용 가능성
  • rows가 과도하게 큼: 읽는 양이 너무 많음
  • Using filesort, Using temporary: 정렬/임시 테이블 비용 가능성

이런 신호는 slow query 분석의 출발점이 됩니다.

인덱스는 왜 중요한가

많은 slow query는 결국 필요한 행만 빠르게 찾지 못해서 생깁니다. 인덱스가 맞지 않으면 MySQL은 훨씬 많은 데이터를 읽어야 합니다.

특히 아래 경우를 자주 봅니다.

  • WHERE 조건 컬럼에 인덱스 없음
  • 조인 키에 인덱스 없음
  • ORDER BY와 조건 순서가 어긋남
  • 함수 적용으로 인덱스를 못 탐

즉, 인덱스가 있다는 사실보다 “이 쿼리 패턴에 맞는 인덱스인가”가 더 중요합니다.

자주 보이는 실수

1. SELECT * 를 습관적으로 사용한다

필요 없는 컬럼까지 많이 읽으면 I/O가 커지고, 커버링 인덱스 이점도 줄어들 수 있습니다.

2. LIMIT 없이 큰 결과를 그대로 읽는다

데이터 탐색용 쿼리가 서비스 요청 경로에 들어오면 급격히 느려질 수 있습니다.

3. 인덱스를 너무 많이 추가한다

읽기 성능은 좋아질 수 있어도 쓰기 비용과 관리 복잡도가 커집니다.

정리할 때 어떤 관점이 좋을까

slow query를 볼 때는 아래 질문이 좋습니다.

  • 이 쿼리는 몇 row를 읽는가
  • 정말 필요한 row만 읽는가
  • 인덱스로 바로 찾을 수 있는가
  • 정렬과 조인 비용이 큰가

이 질문에 답하면서 보면 원인을 훨씬 빨리 좁힐 수 있습니다.

FAQ

Q. 인덱스만 추가하면 무조건 해결되나

아닙니다. 잘못된 인덱스는 효과가 거의 없고, 쿼리 구조 자체를 바꿔야 할 때도 많습니다.

Q. EXPLAIN만 보면 충분한가

출발점으로는 좋지만, 실제 트래픽과 데이터 분포까지 봐야 더 정확합니다.

Q. 입문자는 무엇부터 익히면 좋을까

EXPLAIN, 인덱스 기본, WHERE/ORDER BY/JOIN 관계를 먼저 익히면 매우 큰 도움이 됩니다.

먼저 읽어볼 가이드

검색 유입이 많은 핵심 글부터 이어서 보세요.