EXPLAIN ANALYZE: 쿼리 프로파일링
EXPLAIN ANALYZE: 쿼리 프로파일링 (EXPLAIN ANALYZE: Profile Queries - explain-analyze)
EXPLAIN이 쿼리를 실행하지 않고 플랜만 보여준다면, EXPLAIN ANALYZE는 쿼리를 실제로 실행하면서 각 연산자의 런타임 성능 수치까지 보여줘요. 진짜 실행 시간과 실제 카디널리티를 알고 싶을 때 딱 맞는 명령이에요.
기본 사용법 (Usage)
쿼리 앞에 EXPLAIN ANALYZE를 붙이면 쿼리 플랜을 예쁘게 출력하면서 동시에 실행해요. 각 연산자의 런타임 성능 수치, 추정 카디널리티(EC)와 실제 카디널리티까지 제공해주죠.
EXPLAIN ANALYZE SELECT * FROM tbl;
주의할 점 (Notes)
- 각 연산자에 소요된 누적(cumulative) 벽시계 시간(wall-clock time) 이 표시돼요. 여러 스레드가 병렬로 쿼리를 처리할 때, 쿼리의 총 처리 시간은 개별 연산자에 걸린 시간의 합보다 낮을 수 있어요. 그래서 각 연산자 시간을 다 더하면 총 시간보다 커진다는 점을 기억하세요.
- 다중 파일 읽기(예: 여러 Parquet 파일 읽기) 경우, 출력에 읽어들이는 파일 이름이 포함돼요.
예제 (Example)
아래는 어떤 쿼리에 EXPLAIN ANALYZE를 실행한 예시예요.
EXPLAIN ANALYZE
SELECT name
FROM students
JOIN exams USING (sid)
WHERE name LIKE 'Ma%';
┌─────────────────────────────────────┐
│┌───────────────────────────────────┐│
││ Total Time: 0.0008s ││
│└───────────────────────────────────┘│
└─────────────────────────────────────┘
┌───────────────────────────┐
│ EXPLAIN_ANALYZE │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ 0 │
│ (0.00s) │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│ PROJECTION │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ name │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ 2 │
│ (0.00s) │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│ HASH_JOIN │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ INNER │
│ sid = sid │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ├──────────────┐
│ EC: 1 │ │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │
│ 2 │ │
│ (0.00s) │ │
└─────────────┬─────────────┘ │
┌─────────────┴─────────────┐┌─────────────┴─────────────┐
│ SEQ_SCAN ││ FILTER │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ││ prefix(name, 'Ma') │
│ exams ││ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ││ EC: 1 │
│ sid ││ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ││ 2 │
│ EC: 3 ││ (0.00s) │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ││ │
│ 3 ││ │
│ (0.00s) ││ │
└───────────────────────────┘└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│ SEQ_SCAN │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ students │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ sid │
│ name │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Filters: name>=Ma AND name│
│ <Mb AND name IS NOT NULL │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ EC: 1 │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ 2 │
│ (0.00s) │
└───────────────────────────┘
출력을 잘 살펴보면, EXPLAIN의 경우와 달리 여기서는 각 연산자가 처리한 실제 행 수(예: HASH_JOIN 아래의 2, SEQ_SCAN 아래의 3)와 소요 시간이 추가로 표시되는 걸 볼 수 있어요. 추정값(EC)과 실제값을 비교해서 옵티마이저가 얼마나 정확한지도 확인할 수 있죠.