C.W.K.
Stream
Lesson 01 of 10 · published

인덱스가 뭐야 — B-tree 설명

~14 min · indexes, b-tree, performance

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

모든 거 밑에 있는 자료구조

인덱스 없으면 모든 WHERE col = ?full table scan: SQLite 가 모든 row 읽고, predicate 체크하고, 매치 반환. O(n). 1000 만 row 면 몇 초, 1 만 row 면 안 보임.

인덱스 = 인덱싱된 컬럼(들) 을 정렬된 순서로 + row 로 가는 포인터로 저장하는 별도 B-tree 자료구조. 인덱스 있으면 WHERE col = ? 가 O(log n) — 테이블 사이즈와 무관하게 page read 몇 번.

SQLite 가 쓰는 B-tree access 3 가지:

  • EqualityWHERE col = ? 가 매치 키까지 트리 walk.
  • RangeWHERE col BETWEEN a AND b 가 첫 매치까지 walk 후 forward scan.
  • Prefix on TEXT — WHERE col LIKE 'pre%' 가 인덱스 사용 (시작 prefix 알려짐); '%suf' 는 못 함.
Principle: 모든 INTEGER PRIMARY KEY 가 이미 인덱스 — SQLite 가 아무 거 안 해도 id 로 즉시 row 찾는 이유. FK 는 자동 인덱싱 안 됨, 직접 인덱스 만들어야 하고 거의 항상 만들어야 해.

Code

인덱스 유무에 따른 query 동작 변화·sql
CREATE TABLE big(id INTEGER PRIMARY KEY, email TEXT, name TEXT) STRICT;

-- 100k row insert (single transaction!)
WITH RECURSIVE cnt(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM cnt WHERE x<100000)
INSERT INTO big(email, name)
SELECT 'user'||x||'@x.com', 'User '||x FROM cnt;

.timer on
SELECT * FROM big WHERE email = 'user99999@x.com';
-- Run Time: real 0.045 user 0.040 ...   (full scan)

CREATE INDEX idx_big_email ON big(email);
SELECT * FROM big WHERE email = 'user99999@x.com';
-- Run Time: real 0.000 user 0.000 ...   (인덱스 사용)

External links

Exercise

위 demo 본인 머신 실행. 그 다음 query 3 개 더: (1) WHERE email LIKE 'user1%', (2) WHERE email LIKE '%@x.com', (3) WHERE email != 'user1@x.com'. .timer on + EXPLAIN QUERY PLAN 으로 인덱스 어떤 거 돕고 어떤 게 scan 으로 떨어지는지 확인.

Progress

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

댓글 0

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

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