본문 바로가기
WIKI 기술 지식 베이스

EXPLAIN

원문 보기 위키 갱신

SQL 문장을 실제로 실행하지 않고도 어떻게 처리될지 들여다보게 해 주는 EXPLAIN 문이에요. 가상 머신 바이트코드를 보는 EXPLAIN과 쿼리 실행 전략을 보여 주는 EXPLAIN QUERY PLAN, 두 가지 형태가 있어요.

출처: 문서

본문

EXPLAIN 문은 Turso가 SQL 문장을 어떻게 실행하는지에 대한 정보를 보여 줘요. 두 가지 형태가 있는데, EXPLAIN은 가상 머신 바이트코드를 보여 주고 EXPLAIN QUERY PLAN은 더 높은 수준의 쿼리 실행 전략을 보여 줘요.

Syntax

EXPLAIN statement;
EXPLAIN QUERY PLAN statement;
Parameter Type Description
statement SQL 어떤 SQL 문장이든 (SELECT, INSERT, UPDATE, DELETE 등)

EXPLAIN

EXPLAIN 접두어를 붙이면 Turso가 문장을 실행하는 대신, 그 문장을 실행하는 데 쓰일 가상 머신(VDBE) opcode의 나열을 돌려줘요.

EXPLAIN SELECT * FROM users WHERE id = 1;
-- addr | opcode     | p1 | p2 | p3 | p4       | p5
-- 0    | Init       | 0  | 9  | 0  |          | 0
-- 1    | OpenRead   | 0  | 2  | 0  | 3        | 0
-- 2    | SeekRowid  | 0  | 8  | 1  |          | 0
-- ...

Output Columns

Column Description
addr 명령어 주소 (순차적인 정수)
opcode 연산 이름 (예: OpenRead, SeekRowid, Column, ResultRow)
p1 첫 번째 피연산자
p2 두 번째 피연산자
p3 세 번째 피연산자
p4 네 번째 피연산자 (테이블 이름이나 콜레이션처럼 문자열 값인 경우가 많아요)
p5 다섯 번째 피연산자 (플래그)

EXPLAIN QUERY PLAN

EXPLAIN QUERY PLAN 접두어는 쿼리 옵티마이저가 문장을 실행하기 위해 선택한 전략을 높은 수준에서 설명해 줘요. 쿼리 성능을 이해할 때는 날것의 EXPLAIN보다 이 출력이 훨씬 유용해요.

EXPLAIN QUERY PLAN SELECT * FROM users WHERE name = 'Alice';
-- id | parent | notused | detail
-- 2  | 0      | 0       | SCAN users
CREATE INDEX idx_name ON users(name);
EXPLAIN QUERY PLAN SELECT * FROM users WHERE name = 'Alice';
-- id | parent | notused | detail
-- 3  | 0      | 0       | SEARCH users USING INDEX idx_name (name=?)

Output Columns

Column Description
id 이 단계의 고유 식별자
parent 부모 단계의 id (최상위는 0)
notused 향후 사용을 위해 예약됨 (항상 0)
detail 실행 단계를 사람이 읽을 수 있는 형태로 설명한 내용

Common Detail Messages

Detail Pattern Meaning
SCAN table 전체 테이블 스캔 (인덱스를 사용하지 않음)
SEARCH table USING INDEX idx (col=?) 지정한 컬럼에 대한 인덱스 조회
SEARCH table USING INTEGER PRIMARY KEY (rowid=?) rowid 직접 조회
USE TEMP B-TREE FOR ORDER BY 정렬을 위해 임시 B-트리를 사용함
USE TEMP B-TREE FOR DISTINCT 중복 제거를 위해 임시 B-트리를 사용함
COMPOUND SUBQUERY UNION, INTERSECT, EXCEPT 중 하나를 의미함
CORRELATED SCALAR SUBQUERY 단일 값을 돌려주는 상관 서브쿼리

Examples

Comparing Query Plans

CREATE TABLE orders (
    id INTEGER PRIMARY KEY,
    customer_id INTEGER,
    total REAL
);

-- 인덱스가 없을 때: 전체 테이블 스캔
EXPLAIN QUERY PLAN SELECT * FROM orders WHERE customer_id = 42;
-- SCAN orders

-- 인덱스를 만든 후
CREATE INDEX idx_customer ON orders(customer_id);
EXPLAIN QUERY PLAN SELECT * FROM orders WHERE customer_id = 42;
-- SEARCH orders USING INDEX idx_customer (customer_id=?)

Join Order

EXPLAIN QUERY PLAN
SELECT o.id, c.name
FROM orders o
INNER JOIN customers c ON c.id = o.customer_id
WHERE c.name = 'Alice';
-- SCAN orders AS o
-- SEARCH customers AS c USING INTEGER PRIMARY KEY (rowid=?)

Subqueries

EXPLAIN QUERY PLAN
SELECT * FROM orders
WHERE customer_id IN (SELECT id FROM customers WHERE active = 1);
-- SCAN orders
-- LIST SUBQUERY
--   SCAN customers

See Also

  • ANALYZE for collecting statistics that improve query plans
  • CREATE INDEX for creating indexes to speed up queries

더 알아보기 (Learn more)

  • ANALYZE - 쿼리 플랜을 개선하는 통계 수집
  • CREATE INDEX - 쿼리를 빠르게 하는 인덱스 생성
  • SELECT - EXPLAIN으로 분석하게 되는 SELECT 문