G·Graph Daily Lab
DAY 46 / 100
내 학습 기록
DAY 46개념·실험그래프 DB 엔진과 선택

시작점을 빨리 찾는 인덱스

순회는 국소적이지만 출발점은 찾아야 합니다. 앵커 노드를 찾는 인덱스가 있을 때와 없을 때의 차이를 봅니다.

약 20분조작형 실험 확인 퀴즈
A SMALL DETOUR

이번 회차, 내 속도로.

기초를 더 짚거나 궁금한 주제로 잠깐 넓혀 보세요. 최대 3단계를 거쳐 DAY 46로 돌아옵니다.

난이도·관심 주제 고르기
이번 회차는 어느 속도로 볼까요?
더 살펴볼 주제 1~2개 선택

1/2개 선택 · 새 보충·심화 수업과 본과정 다시 읽기를 선택할 수 있어요.

이렇게 다녀와요 1단계 · 약 12분

  1. 출발 · DAY 46인덱스·앵커 노드
  2. 1. 관심 주제ACID·격리 수준추가 19 · 새 추가 수업
  3. 복귀 · DAY 46원래 회차 이어가기
  • ACID·격리 수준 · DAY 49에서 트랜잭션 순회(OLTP) 워크로드를 봤다면, 그 ‘트랜잭션’이 무엇을 보장하고 무엇을 보장하지 않는지 확인하러 옵니다.

선택과 경로 기록은 이 브라우저에 저장됩니다. 본과정의 회차 완료와는 별도입니다.

복귀: DAY 46 → 본과정 다음 회차: DAY 47

핵심 개념

MATCH (p:Person {email:'minsu@lab.kr'})-[:AUTHORED]->(x:Paper) RETURN x.title에서 관계를 따라가는 부분은 인접 참조로 빠르게 진행됩니다(DAY 28). 그러나 먼저 email이 일치하는 민수 노드, 곧 앵커(anchor) 노드를 찾아야 합니다. 인덱스가 없으면 엔진은 :Person 노드를 모두 읽으며 email을 비교하는 레이블 스캔을 합니다.

Neo4j에서는 CREATE INDEX person_email FOR (p:Person) ON (p.email)로 속성 인덱스를 만듭니다. 종류를 지정하지 않으면 범위(range) 인덱스가 생기고, 유일성 제약(DAY 29)을 걸면 같은 이름의 인덱스가 함께 생깁니다. 레이블과 관계 타입을 찾는 토큰 조회 인덱스는 DB를 만들 때 기본으로 생기며, 문자열 검색용 텍스트 인덱스와 임베딩용 벡터 인덱스(DAY 48)도 있습니다.

비용 감각은 이렇습니다. 스캔은 노드 N개를 모두 확인하고, 정렬된 트리 구조의 인덱스는 대략 log₂N 단계면 값을 찾습니다. N이 1,048,576(2^20)이면 스캔 1,048,576번 대 약 20단계입니다. 실제 B-트리는 한 노드에 키를 많이 담아 단계가 더 적으므로, 이 수치는 크기 감각을 위한 근사입니다.

인덱스에도 비용이 있습니다. 쓰기마다 인덱스를 갱신해야 하고 저장 공간을 씁니다. 조건이 거의 모든 노드에 해당하면(예: 모든 사람이 같은 국가) 인덱스의 이점이 작습니다. 또 toLower(p.email)처럼 속성에 함수를 씌우면 일반 인덱스를 쓰지 못할 수 있습니다. 인덱스가 실제로 쓰였는지는 실행 계획에서 확인합니다.

그래프 순회도 앵커 노드를 찾을 때는 인덱스가 필요하며, 인덱스가 없으면 레이블 전체를 스캔합니다.

작은 예제로 따라가기

01

Person 1,000명: 스캔 1,000번, 인덱스는 log₂1000 ≈ 10단계입니다.

02

Person 1,000,000명: 스캔 1,000,000번, 인덱스는 약 20단계입니다(2^20 ≈ 1,048,576).

03

Person 10,000,000명: 스캔 10,000,000번, 인덱스는 약 24단계입니다(log₂10^7 ≈ 23.3). N이 10배 늘 때 인덱스 단계는 약 3.3씩만 늘어납니다.

직접 실험해 보기

레이블 노드 수를 1,000에서 10,000,000까지 늘리며 인덱스를 끈 상태(스캔 N)와 켠 상태(약 log₂N)의 막대를 비교하고, N이 10배가 될 때 각 막대가 얼마나 변하는지 적으세요.

LIVE EXPERIMENT · INDEX

시작 노드를 스캔할까, 인덱스로 찾을까

민수의 친구를 찾으려면 먼저 시작 노드 민수(앵커)를 찾아야 한다.
레이블 전체 스캔 (N)1,000,000
인덱스 탐색 (≈log₂N)20
지금 방식전체 스캔NodeByLabelScan + Filter
작업량1,000,000노드마다 name 비교
노드 10배 늘면×10그대로 비례
MATCH (p:Person {name: '민수'})
      -[:KNOWS]->(f)
RETURN f.name;
// 1,000,000개를 모두 읽고 거른다
NodeByLabelScan  p:Person
Filter           p.name = '민수'
Expand(All)      (p)-[:KNOWS]->(f)

근사다. 실제 B-트리는 한 노드에 키를 수백 개 담아 깊이가 log₂N보다 훨씬 작다. 인덱스는 시작점(앵커)을 찾을 때만 쓰이고, 찾은 뒤 이웃으로 가는 Expand는 저장된 인접 관계를 따라간다.

이번에는 직접 풀어 보세요

정답을 보기 전에 계산과 이유를 적어 보세요. 해설과 비교하고 확인 표시를 남기면 완료할 수 있습니다.

문제 1
힌트 보기

500,000은 2^19보다 조금 작습니다.

풀이와 비교하기

스캔은 500,000번입니다. 인덱스는 log₂500,000 ≈ 18.9이므로 약 19단계입니다. 약 26,000배 차이지만 근사치이며, 실제 비용은 엔진의 인덱스 구조와 캐시에 따라 다릅니다.

풀이와 확인 표시는 이 브라우저에 저장됩니다.

YOUR NOTES

오늘 이해한 것과 다시 볼 것

계산이 달라진 이유, 헷갈린 개념, 다음에 확인할 질문을 남겨 보세요.

메모는 이 브라우저에 저장됩니다. 홈에서 전체 기록을 내려받을 수 있습니다.

오늘의 이해 확인

그래프 DB에서 속성 인덱스가 주로 빠르게 해 주는 일은?

완료 조건: 확인 퀴즈 정답 · / 직접 풀기 0/1

FURTHER READING

더 깊이 읽기

예제와 실험 데이터는 이 과정을 위해 만든 것입니다. 원문은 선택 자료이며, 강의와 직접 풀기만으로도 다음 회차를 이어갈 수 있습니다.

Cypher Manual: Search-performance indexesNeo4jCypher Manual: Understanding query plansNeo4j

이 자료는 개념 학습용입니다. 실제 데이터베이스·라이브러리·플랫폼의 동작과 설정은 제품과 버전마다 다를 수 있습니다.