인덱스 트레이드오프 트랜잭션 ACID 📝 문제풀이
◀ 이전 🎉 완주 · 목차
CHAPTER 10 · 고급

인덱스·뷰·트랜잭션, 실전을 위한 마지막 열쇠

데이터를 빠르게 찾고(인덱스), 편하게 재사용하고(뷰), 안전하게 처리하는(트랜잭션) 세 가지를 배워요. 실무에서 매일 마주치는 개념들이에요. 마지막 장까지 힘내요!

🎯 이 장을 끝내면
인덱스
인덱스(INDEX) — 조회 속도를 높이는 "책의 색인"
데이터가 많아질수록 진가를 발휘하는 성능의 핵심이에요.

두꺼운 책에서 특정 단어를 찾을 때, 맨 앞부터 한 장씩 넘기면 너무 느려요. 그래서 책 뒤에는 색인(찾아보기)이 있죠 — "그 단어는 몇 페이지"라고 미리 정리해둔 표예요. 인덱스(INDEX)는 데이터베이스의 색인이에요. 특정 열에 색인을 만들어 두면, DB가 처음부터 전부 훑지 않고 바로 원하는 행으로 점프할 수 있어요.

-- users 테이블의 name 열에 인덱스 생성
CREATE INDEX idx_name ON users(name);

이렇게 name에 인덱스를 걸어두면, WHERE name = '철수' 같은 조회가 훨씬 빨라져요. 인덱스는 특히 WHERE(조건 검색) · JOIN(테이블 연결) · ORDER BY(정렬)에서 성능이 크게 좋아져요.

📖 색인 비유로 한 번 더 인덱스 없음 — 100만 행을 처음부터 끝까지 다 뒤짐(전체 스캔). 느려요.
인덱스 있음 — 정렬된 색인을 보고 원하는 위치로 바로 점프. 빨라요. 💡 즉 인덱스는 "찾기 좋게 미리 정리해 둔 지도"예요. 데이터가 많을수록 효과가 커집니다.
INDEX CREATE INDEX 조회 속도 WHERE JOIN ORDER BY VIEW TRANSACTION COMMIT ROLLBACK ACID
🧭
인덱스는 "조회 성능"을 위한 도구. 데이터 자체를 바꾸는 게 아니라, 찾는 속도만 빠르게 해주는 보조 구조물이에요. 뒤에 나오는 트레이드오프까지 함께 알아야 제대로 쓸 수 있어요.
⚖️
트레이드오프
공짜는 없다 — 인덱스의 대가
"많이 걸수록 좋다"가 아니에요. 꼭 필요한 곳에만.

인덱스는 조회를 빠르게 하지만, 대가가 있어요. 인덱스도 결국 추가로 관리해야 하는 데이터이기 때문이에요.

🔤
트레이드오프(trade-off) — 하나를 얻으면 다른 하나를 내주는 "맞바꿈" 관계예요. 인덱스는 조회 속도(얻는 것)를 높이는 대신 쓰기 속도·저장공간(내주는 것)을 희생해요. 그래서 "무조건 좋은 것"이 아니라, 득과 실을 견줘 필요한 곳에만 써야 해요.
구분인덱스가 있으면
조회 (SELECT)빨라짐 — 색인으로 바로 점프
쓰기 (INSERT·UPDATE·DELETE)⚠️ 느려짐 — 데이터가 바뀔 때마다 색인도 같이 갱신해야 함
저장공간⚠️ 더 씀 — 색인 자체가 공간을 차지함
✍️ 왜 쓰기가 느려질까? 데이터를 새로 INSERT하거나 UPDATE·DELETE하면, 테이블뿐 아니라 그 열에 걸린 인덱스(색인)도 함께 다시 정리해야 해요. 책에 내용을 추가할 때마다 뒤 색인도 고쳐야 하는 것과 같죠. 그래서 INSERT·UPDATE·DELETE(쓰기)는 느려지고, 인덱스가 차지하는 만큼 저장공간도 더 씁니다.
⚠️
모든 열에 다 걸면 안 돼요. 인덱스를 남발하면 조회는 조금 빨라져도 쓰기가 크게 느려지고 공간만 낭비돼요. 자주 조건·정렬·조인에 쓰이는 열에만 선별해서 거는 게 정석이에요.
🪟
뷰(VIEW) — 자주 쓰는 쿼리를 저장한 "가상 테이블"
복잡한 쿼리를 이름 하나로 재사용해요.

매번 길고 복잡한 SELECT를 다시 쓰긴 번거로워요. 뷰(VIEW)는 자주 쓰는 쿼리에 이름을 붙여 저장한 "가상 테이블"이에요. 한 번 만들어 두면, 그 뒤로는 진짜 테이블처럼 간단히 SELECT할 수 있어요.

-- 성인(20세 이상)만 보여주는 뷰 만들기
CREATE VIEW adult AS
SELECT * FROM users WHERE age >= 20;

-- 이제 뷰를 진짜 테이블처럼 사용
SELECT * FROM adult;
🪟 "가상" 테이블인 이유 뷰는 실제 데이터를 따로 저장하지 않아요. 뷰를 조회하면, DB가 저장해 둔 쿼리를 그때그때 실행해서 결과를 보여줘요. 그래서 원본 users의 데이터가 바뀌면, adult 뷰의 결과도 자동으로 최신 상태가 됩니다. 창(window)으로 원본을 들여다보는 셈이에요.
💡
뷰의 장점: ① 복잡한 쿼리를 간단히 재사용, ② 자주 쓰는 조건을 이름 하나로 표준화, ③ 사용자에게 필요한 열만 노출(보안). 다만 뷰는 데이터를 별도 저장하지 않는 "정의(쿼리)"라는 점을 기억하세요.
🔒
트랜잭션
트랜잭션(TRANSACTION) — 여러 작업을 "하나의 묶음"으로
모두 성공 아니면 전부 취소. 데이터 안전의 핵심이에요.

계좌 이체를 생각해봐요. "A에서 출금"과 "B에 입금", 두 작업이 있어요. 만약 출금은 됐는데 입금 도중 오류가 나면? 돈이 공중으로 사라져요. 그래서 이 둘은 반드시 하나로 묶여 처리돼야 해요.

트랜잭션은 여러 SQL 작업을 하나의 묶음으로 다루는 단위예요. 묶음 안의 작업이 모두 성공하면 COMMIT(확정), 하나라도 실패하면 ROLLBACK(전부 되돌리기)이에요.

BEGIN;                                        -- 트랜잭션 시작
UPDATE accounts SET balance = balance - 100   -- ① A 계좌에서 출금
  WHERE id = 1;
UPDATE accounts SET balance = balance + 100   -- ② B 계좌에 입금
  WHERE id = 2;
COMMIT;                                        -- 둘 다 성공 → 확정!
-- 만약 중간에 문제가 있었다면:  ROLLBACK;   -- 전부 취소, 원래대로
🏦 계좌 이체 비유 둘 다 성공COMMIT: 출금·입금이 모두 확정돼요. 이체 완료!
하나라도 실패ROLLBACK: 출금까지 됐더라도 없던 일로 되돌려요. 돈이 사라지지 않아요. 💡 즉 트랜잭션은 "전부 되거나, 전부 안 되거나"를 보장해요. 중간에 어중간하게 끊긴 상태를 허용하지 않아요.
🔑
핵심 명령: BEGIN(시작) · COMMIT(성공 확정) · ROLLBACK(실패 시 되돌리기). "성공하면 커밋, 실패하면 롤백" 이 한 줄만 확실히 기억하세요.
🧪
ACID
트랜잭션이 지키는 4가지 성질, ACID
이름의 앞글자를 딴 것 — 뜻만 가볍게 잡아두면 돼요.

트랜잭션이 믿을 수 있게 처리되려면 갖춰야 할 4가지 성질이 있어요. 앞글자를 따서 ACID라고 불러요.

ACID — 트랜잭션의 4대 성질
글자이름
A원자성 (Atomicity)전부 성공 또는 전부 실패 (쪼개지지 않음)
C일관성 (Consistency)규칙을 지켜, 데이터가 항상 올바른 상태 유지
I고립성 (Isolation)동시에 실행돼도 서로 간섭하지 않음
D지속성 (Durability)COMMIT된 결과는 영구히 남음 (장애에도 보존)
🧭
지금은 "A=원자성, C=일관성, I=고립성, D=지속성" 정도만 잡아두세요. 특히 원자성(Atomicity)이 앞에서 본 COMMIT/ROLLBACK("전부 되거나 전부 안 되거나")과 직접 연결돼요.
🧠 이 장 핵심 요약
📝
문제풀이 · 점검
배운 걸 가볍게 점검해봐요
시험이 아니라 "내가 이해했나" 확인용이에요. 틀려도 바로 해설이 나와요.
🧪
문제를 풀면 즉시 정답과 해설이 나오고, 위쪽 바에 점수가 쌓여요. 네 가지 유형(객관식 · O/X · 빈칸 · 쿼리결과)을 섞어 두었어요.
🎉 완주 🗺️ 전체 로드맵으로 — 열 개 장을 모두 마쳤어요! 배운 걸 로드맵에서 되돌아봐요