Foundry
데이터베이스
중급
핵심

EXPLAIN 실행 계획

type, key, rows, Extra 컬럼 해석

EXPLAIN 실행 계획

핵심 개념

DB가 쿼리를 어떻게 실행할지 보여주는 분석 도구.

EXPLAIN SELECT * FROM orders
WHERE user_id = 123
ORDER BY created_at DESC;

EXPLAIN 결과 읽기 (MySQL)

+----+------+-------+------+------+----------+
| id | type | table | key  | rows | Extra    |
+----+------+-------+------+------+----------+
| 1  | ref  | orders| idx  | 15   | Using .. |
+----+------+-------+------+------+----------+

type 컬럼 (접근 방식, 성능순)

type의미성능
constPK/유니크 1건최고
ref인덱스 동등 조건좋음
range인덱스 범위 스캔보통
index인덱스 풀 스캔나쁨
ALL테이블 풀 스캔최악

Extra 컬럼의 핵심 키워드

Using index       → 커버링 인덱스 (좋음!)
Using where       → WHERE 필터링 (보통)
Using filesort    → 정렬 추가 수행 (주의)
Using temporary   → 임시 테이블 생성 (주의)
Using index condition → 인덱스 컨디션 푸시다운

실무 튜닝 예시

-- 느린 쿼리
EXPLAIN SELECT * FROM orders
WHERE status = 'pending'
ORDER BY created_at;
-- type: ALL, Extra: Using filesort ← 풀스캔 + 정렬!

-- 인덱스 추가 후
CREATE INDEX idx_status_date
  ON orders (status, created_at);

EXPLAIN SELECT * FROM orders
WHERE status = 'pending'
ORDER BY created_at;
-- type: ref, Extra: Using index condition ← 개선!

PostgreSQL EXPLAIN 차이

-- PostgreSQL은 비용 정보 제공
EXPLAIN ANALYZE SELECT ...

-- 결과 예시
Seq Scan on orders
  (cost=0.00..1234.00 rows=100 width=52)
  (actual time=0.5..15.2 rows=98 loops=1)
항목의미
cost예상 비용 (상대값)
rows예상 행 수
actual time실제 실행 시간
ANALYZE실제 실행하여 측정
면접에서 이렇게 나옵니다

Q.EXPLAIN 결과에서 type이 ALL이면 어떤 의미이고, 어떻게 개선하나요?

풀 테이블 스캔입니다. 인덱스를 쓰지 못하고 모든 행을 읽습니다.

원인부터 확인합니다.

원인조치
조건 컬럼에 인덱스가 없다인덱스를 만든다
컬럼에 함수를 씌웠다범위 조건으로 다시 쓴다
타입이 다르다값의 타입을 맞춘다
복합 인덱스의 선행 컬럼이 없다순서를 바꾸거나 다른 인덱스를 만든다
조건이 대부분의 행에 해당한다정상이다. 풀 스캔이 더 빠르다

마지막 경우가 중요합니다. 결과가 전체의 30%를 넘으면 옵티마이저가 일부러 풀 스캔을 고릅니다. 인덱스로 하나씩 찾아 테이블을 왕복하는 것보다 순차로 다 읽는 것이 빠르기 때문입니다.

흔한 실수: ALL 을 보면 무조건 인덱스를 추가하는 것. 작은 테이블이거나 대부분을 읽는 쿼리면 인덱스가 오히려 느립니다.

Q.Using filesort와 Using temporary는 각각 어떤 상황에서 발생하나요?

표시언제
Using filesortORDER BY 를 인덱스로 해결하지 못할 때결과를 따로 정렬한다
Using temporaryGROUP BY, DISTINCT, 일부 UNION중간 결과를 임시 테이블에 담는다

이름이 오해를 부릅니다. filesort 는 반드시 파일을 쓰는 것이 아니라, 정렬 버퍼로 끝나면 메모리에서 처리합니다. 결과가 크면 디스크를 씁니다.

해결 방향입니다.

상황조치
ORDER BY 컬럼이 인덱스에 없다정렬 컬럼까지 포함한 복합 인덱스
WHERE 와 ORDER BY 컬럼이 다른 인덱스하나의 복합 인덱스로 합친다
GROUP BY 가 인덱스 순서와 다르다인덱스 순서를 맞춘다
정렬 대상이 너무 많다먼저 걸러내거나 커서 페이지네이션으로 바꾼다

흔한 실수: 둘 다 무조건 나쁘다고 보는 것. 결과가 수십 행이면 정렬 비용이 미미합니다. 수십만 행을 정렬할 때 문제가 됩니다.

Q.느린 쿼리를 발견했을 때 어떤 순서로 분석하나요?

순서하는 일
1실제로 느린지 확인한다. 평균인지 특정 조건에서만인지
2실행 계획을 본다. 스캔 방식, 읽은 행 수, 정렬과 임시 테이블
3예상과 실제를 비교한다. 크게 다르면 통계가 오래된 것이다
4인덱스로 풀리는지 본다. 없거나, 있는데 못 타는지
5쿼리를 고친다. 함수 제거, 조인 순서, 불필요한 컬럼 제거
6그래도 안 되면 구조를 본다. 파티셔닝, 캐시, 반정규화

3번이 자주 빠집니다. 옵티마이저가 예상한 행 수와 실제가 수백 배 다르면 잘못된 계획을 고르고, 원인은 통계가 낡은 것입니다. 통계 갱신만으로 해결되는 경우가 있습니다.

같은 쿼리라도 파라미터에 따라 계획이 달라질 수 있으므로, 문제가 된 실제 값으로 확인해야 합니다.

흔한 실수: 계획만 보고 실제 실행을 안 해보는 것. 예상 비용과 실제 소요는 다릅니다. 실측 옵션으로 실제 행 수와 시간을 함께 봐야 합니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

데이터베이스 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.