Skip to content
난이도 면접 빈출문제은행 6

B-Tree 활용 ​

인덱스를 "만드는 법"이 아니라 쿼리가 인덱스를 "타는 법", 즉 실제로 인덱스를 써서 읽게 만드는 법을 다룬다. 다중 칼럼 인덱스의 칼럼 순서, 좌측 접두어 규칙(leftmost prefix rule), 커버링 인덱스(covering index), 정렬 생략이 핵심이다. 면접에 자주 나오는 질문이 대부분 여기 모여 있다.

다중 칼럼 인덱스와 좌측 접두어 ​

(a, b, c) 인덱스는 세 인덱스가 아니다. a로 정렬하고, a가 같으면 b로, 또 같으면 c로 정렬한 하나의 전화번호부다. 성으로 정렬된 전화번호부에서 이름만으로는 사람을 찾을 수 없듯이, 이 정렬 순서 때문에 쓸 수 있는 조건이 정해진다. 아래 표의 △는 탐색 범위를 좁히는 데는 일부 칼럼만 쓰이고, 나머지 칼럼은 읽어 온 항목을 버리는 필터나 ICP(Index Condition Pushdown, 인덱스 조건 푸시다운)로 거른다는 뜻이다.

조건사용
a = ?◯
a = ? AND b = ?◯
a = ? AND b = ? AND c = ?◯
b = ?✕ (a 없이 시작 불가)
a = ? AND c = ?△ (a로 범위를 찾고 c는 주로 필터)
a > ? AND b = ?△ (a 범위 안에서 b는 필터·ICP에 활용 가능)

기본 규칙은 좌측 접두어 규칙이다. 인덱스의 맨 왼쪽 칼럼부터 빠짐없이 이어진 조건이 탐색 범위, 즉 인덱스의 어디서 읽기 시작해 어디서 멈출지를 만든다. 범위 조건 뒤 칼럼도 ICP로 인덱스를 읽는 단계에서 먼저 걸러질 수 있지만, 보통 탐색 시작·종료 범위를 더 좁히지는 못한다. 읽는 인덱스 구간은 줄지 않고, 그 구간에서 조건에 안 맞는 항목을 버릴 뿐이다. MySQL의 스킵 스캔(skip scan) 같은 예외 최적화도 있으니, 실제로 어떻게 읽는지는 실행 계획(execution plan)으로 확인한다.

커버링 인덱스: 테이블에 안 가기 ​

세컨더리 인덱스(secondary index)의 리프에는 인덱스 키 칼럼 값이 들어 있다. 그래서 SELECT 목록이 인덱스 칼럼 안에 포함되면 인덱스만 읽고 답을 낼 수 있어 테이블 행을 읽을 필요가 없다. 이런 경우를 커버링이라 한다. 실행 계획을 보여 주는 EXPLAIN의 Extra 칼럼에 Using index가 나오면 커버링이 됐다는 표시다. 인덱스에서 찾은 행마다 테이블의 다른 페이지(page)로 건너뛰어 읽는 랜덤 I/O(Input/Output, 입출력)를 통째로 생략하므로 효과가 크다.

sql
-- (user_id, created_at) 인덱스가 있을 때
SELECT created_at FROM orders WHERE user_id = 42;  -- Using index, 테이블 접근 없음
SELECT * FROM orders WHERE user_id = 42;           -- 행을 읽어야 해서 테이블 접근

정렬·그룹 회피와 스캔 방향 ​

  • 인덱스는 이미 정렬돼 있다. 그래서 WHERE의 선행 칼럼(인덱스 정의에서 앞쪽에 있는 칼럼) 조건과 ORDER BY가 인덱스 순서에 맞으면, 결과를 따로 정렬하는 파일소트(filesort) 없이 인덱스 순서대로 읽기만 하면 된다. (a,b) 인덱스에서 ORDER BY b만 쓰려면 보통 a = 상수처럼 선행 칼럼이 고정돼야 한다. a가 하나로 고정돼야 그 안에서 b가 정렬된 순서로 나오기 때문이다. 전체 인덱스는 역방향으로도 스캔할 수 있어서, 인덱스 순서를 그대로 뒤집은 정렬에도 쓰인다.
  • GROUP BY도 같은 원리로, 인덱스 순서대로 읽으면서 같은 값끼리 묶어 집계할 수 있다. 단 8.0부터 서버는 GROUP BY 결과의 정렬을 보장하지 않으므로, 정렬된 결과가 필요하면 ORDER BY를 명시한다.
  • (a ASC, b DESC)처럼 칼럼마다 정렬 방향이 섞인 쿼리가 잦으면, 8.0의 내림차순 인덱스(descending index)로 인덱스의 정렬 방향을 쿼리에 맞춰 준다.

가용성과 효율성 체크리스트 ​

  1. 좌측부터 썼는가 (접두어)
  2. 범위 조건 뒤 칼럼을 과신하지 않았는가
  3. 커버링이 되는가 (Using index)
  4. 파일소트·임시 테이블(temporary table)이 사라지는가 (EXPLAIN 확인)
  5. 카디널리티(cardinality)가 낮은 선행 칼럼은 아닌가

면접 포인트 ​

  • "(a,b) 인덱스에서 b=?는?" → 못 탄다. 전화번호부 비유가 가장 설득력 있다.
  • "커버링 인덱스가 뭔가요?" → 테이블 접근 생략 + Using index. SELECT * 와의 대비.
  • "ORDER BY가 느려요" → 인덱스 순서 일치 여부 → 파일소트. EXPLAIN Extra로 본다.

관련 문서