본문 바로가기
C.W.K.
Stream
Lesson 04 of 10 · published

EXPLAIN QUERY PLAN — 진실 읽기

~14 min · explain, query-plan, performance

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

추측 멈추고 엔진한테 물어봐

아무 query 앞에 EXPLAIN QUERY PLAN만 붙이면 SQLite가 실제로 뭘 할 생각인지 알려줘. 연산 트리를 찍어주는데, 눈여겨볼 단어는 다섯 개야.

  • SCAN — 테이블을 전부 훑겠다는 뜻이야. 작은 테이블이면 싸고 큰 테이블이면 비싸.
  • SEARCH — 인덱스를 타고 찾아간다는 뜻이야. 이게 나오면 좋은 거고.
  • USING INDEX X — 어떤 인덱스를 골랐는지 알려줘.
  • USING COVERING INDEX X — query에 필요한 컬럼이 전부 인덱스 안에 있어서 실제 테이블은 건드리지도 않는다는 뜻이야. 최고지.
  • USE TEMP B-TREE FOR ORDER BY — 정렬에 쓸 인덱스가 없어서 임시로 하나 만들었다는 뜻이야. 정렬용 인덱스가 빠졌다는 신호야.
Tip: EXPLAIN QUERY PLAN은 몸에 배어 있어야 해. 고치기 전에 한 번 보고, 고친 다음에 다시 봐서 plan이 실제로 바뀌었는지 확인해. plan이 그대로인 'fix'는 아무것도 안 고친 거야.

Code

Plan 읽기·sql
EXPLAIN QUERY PLAN
SELECT * FROM messages WHERE conversation_id = 1 ORDER BY created_at DESC LIMIT 20;

-- 유용한 인덱스 없이:
-- 0|0|0|SCAN messages
-- 0|0|0|USE TEMP B-TREE FOR ORDER BY

-- CREATE INDEX idx_msg_conv_created ON messages(conversation_id, created_at DESC) 후:
-- 0|0|0|SEARCH messages USING INDEX idx_msg_conv_created (conversation_id=?)
Plan-driven 최적화 workflow·bash
# 1. 느린 query 식별
sqlite3 myapp.db 'EXPLAIN QUERY PLAN SELECT ...'

# 2. 인덱스 추가/조정
sqlite3 myapp.db 'CREATE INDEX idx_... ON ...'

# 3. 다시 explain — plan 바뀐 거 확인
sqlite3 myapp.db 'EXPLAIN QUERY PLAN SELECT ...'

# 4. Wall-clock 개선 확인
sqlite3 myapp.db '.timer on' 'SELECT ...'

External links

Exercise

네 앱에서 느려 보이는 query를 세 개 골라 각각 EXPLAIN QUERY PLAN을 걸어. SCAN인지 SEARCH인지, ORDER BY가 TEMP B-TREE를 쓰는지, composite 인덱스가 실제로 쓰이는지 적어. 각각에 대해 plan을 바꿀 인덱스를 제안하고 실제로 만들어서 확인해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.