서비스를 운영하다 보면 “페이지가 느려요”, “리포트가 안 떠요” 같은 피드백을 듣게 된다.
이럴 때 원인을 따라가 보면, 그 중심엔 DB 쿼리가 있는 경우가 많다.나도 처음엔 기능만 동작하면 괜찮다고 생각했었다.
하지만 데이터가 쌓이고, 사용자 수가 많아지면서 단 하나의 쿼리가 전체 서비스 성능을 좌우할 수 있다는 걸 알게 되었다.
그래서 우리는 쿼리 튜닝(Query Tuning)을 해야 한다.
다음과 같은 상황을 겪어본 적이 있을 것이다:
이 모든 문제의 공통점은 바로 비효율적인 쿼리다.
특히 MySQL은 쿼리 한 줄의 차이로도 성능이 크게 달라질 수 있다.
MySQL에서는 EXPLAIN 키워드를 사용해 쿼리의 실행 계획을 확인할 수 있다.
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';
이 명령어를 실행하면 MySQL이 해당 쿼리를 어떻게 실행할 예정인지 알려준다.
특히 인덱스를 사용하는지 여부, 스캔하는 행 수, 조인 방식 등을 파악할 수 있다.
| 컬럼 | 설명 |
|---|---|
| type | 접근 방식 (ALL, index, ref, const 등). ALL이면 Full Table Scan |
| key | 실제 사용된 인덱스 이름 |
| rows | 쿼리 실행 시 예측되는 스캔 대상 행 수 |
| Extra | 부가 정보 (Using index, Using where, Using temporary 등) |
type이 ALL이면 풀 테이블 스캔을 의미하므로 성능 개선이 필요하다. ref, const 등은 인덱스를 잘 활용하고 있는 상태다.다음으로 확인할 부분은 WHERE 조건이 인덱스를 타고 있는가다.
SELECT * FROM users WHERE email = 'test@example.com';
만약 email 컬럼에 인덱스가 없다면 이 쿼리는 테이블 전체를 순회하게 된다.
CREATE INDEX idx_users_email ON users(email);
이렇게 인덱스를 추가해주면 쿼리는 훨씬 빠르게 실행되며, EXPLAIN 결과에도 반영된다.
다음과 같은 조건들은 인덱스를 타지 못하는 경우가 많다:
WHERE LEFT(name, 3) = 'Tom'WHERE age + 1 = 30LIKE '%keyword%'이런 경우에는 쿼리를 바꾸거나, FullText Index 또는 다른 구조를 고려해야 한다.
이 글에서는 다음과 같은 내용을 다뤘다:
EXPLAIN으로 실행 계획을 확인하는 방법 사실 쿼리 튜닝은 어렵지 않다.
다음 세 가지 순서만 기억해도 대부분의 성능 문제는 잡을 수 있다:
EXPLAIN으로 실행 계획 확인 💡 당신의 쿼리는 인덱스를 타고 있나요?
지금 바로EXPLAIN으로 확인해보자.