Engine Atlas

Composite Index Anatomy

column order, range boundary, ICP, covering을 실제 plan과 row로 읽기
MySQL 8.4.102026-07-12
English
학습 안내

이 Lab에서 답할 질문

동일한 composite index column이라도 순서가 equality prefix, first range, ICP, row materialization을 어떻게 바꾸나요?

실행 엔진: MySQL 8.4.10
누가 실행하나요?

하나의 Session이 같은 SELECT를 세 가지 index order variant로 실행합니다.

무엇을 고정하나요?

customer_id, status, ordered_at, total_cents가 있는 동일한 orders fixture와 결과 checksum을 고정합니다.

실행 SQL
SELECT id, customer_id, status, ordered_at, total_cents
FROM orders
WHERE customer_id = 412
  AND status = 'PAID'
  AND ordered_at >= '2025-01-01 00:00:00'
ORDER BY ordered_at DESC, id DESC
LIMIT 20;
무엇이 달라지나요?

B-tree 탐색 경계, range candidate 수, ICP 탈락 수, base-row lookup 여부가 index order에 따라 달라집니다.

무엇이 그대로인가요?

WHERE, ORDER BY, LIMIT 20과 반환 rows 및 checksum은 세 variant 모두에서 동일합니다.

먼저 예측해 보세요

customer_id와 status를 먼저 두고 ordered_at range를 뒤에 두면 무엇이 달라질까요?

customer_id와 status를 먼저 두고 ordered_at range를 뒤에 두면 무엇이 달라질까요?

증거 미션

misordered variant의 range candidate 단계를 열어 fixture에서 도출한 M_RANGE candidate 수와 predicate 분류를 확인하세요.

어디를 보나요?
Composite index lens의 range evidence와 candidate·pass·reject 분류를 나란히 봅니다.
이동할 화면
Misordered · range candidates
무엇이 보여야 하나요?
확인할 관찰

M_RANGE는 status='PAID'와 ordered_at 하한을 만족하는 fixture 도출 candidate 31,348개이고, 그중 customer_id=412인 candidate 31개가 통과하며 31,317개는 탈락합니다. 이 수는 engine이 물리적으로 방문한 page나 entry 수가 아닙니다.

근거 경계
Derived · fixture
M_RANGE candidate 31,348과 pass 31·reject 31,317 분류
Checkpoint · evidence로 설명하기misordered fixture의 31,348 candidates, 31 pass, 31,317 reject는 무엇을 뜻하나요?답과 근거 확인

고정 fixture에서 misordered range가 만든 candidate entry를 predicate로 분류한 값입니다. Captured engine이 물리적으로 방문한 page나 entry 수로 해석하면 안 됩니다.

근거 경계
Derived · fixture
candidate·pass·reject entry 분류
이번 Lab의 핵심

composite index는 column 포함 여부보다 equality prefix와 first range의 순서, 그리고 필요한 column을 entry가 품는지가 핵심입니다.

다음 연결

다음 Lab에서는 같은 access path라도 statistics가 실제 row 분포를 얼마나 정확히 추정하는지 비교합니다.

용어 확인
B-tree처음 다루는 Lab 02
정렬된 key를 계층적으로 보관해 equality와 range 탐색을 지원하는 index 구조입니다.
equality prefix처음 다루는 Lab 02
composite index의 왼쪽부터 equality predicate로 고정되어 탐색 범위를 좁히는 연속 key 부분입니다.
first range처음 다루는 Lab 02
composite index 탐색 경계를 만드는 첫 range key part이며, 뒤 key part는 추가 filter나 ICP에 쓰일 수 있습니다.
Index Condition Pushdown (ICP)처음 다루는 Lab 02
storage engine이 base row를 읽기 전에 index entry의 column으로 일부 predicate를 평가하는 최적화입니다.
covering index처음 다루는 Lab 02
query가 필요한 column을 index entry만으로 제공해 base-row lookup을 피할 수 있는 index입니다.

01 · SOURCE

SQL

1 active fragmentMySQLLIMIT 20
SELECT id, customer_id, status, ordered_at, total_cents
FROM orders
WHERE customer_id = 412
  AND status = 'PAID'
  AND ordered_at >= '2025-01-01 00:00:00'
ORDER BY ordered_at DESC, id DESC
LIMIT 20;
02 · FLOW

Native Plan

01 / 12
01/ 12