방대한 데이터 속에서 원하는 정보를 빠르게 찾기 위해 사용하는 색인.
클러스터형 인덱스는 테이블 당 딱 하나만 만들 수 있다. 따라서 클러스터형 인덱스로는 책의 본문을 두가지 순서로 동시에 정렬할 수는 없다.
비클러스터형 인덱스에서 주소를 확인한 뒤 실제 데이터를 가지러 가는 과정을 Lookup이라고 한다. 인덱스만 보고 끝나는 게 아니라 실제 데이터를 찾으로 한 번 더 움직여야 하므로, 너무 많은 데이터를 조회할 때는 오히려 그냥 처음부터 끝까지 다 읽는 Full scan보다 느려질 수 있다.
만약 데이터베이스에 Gemini, Apple, Zebra라는 데이터가 순서 없이 들어있다고 가정해보자. 이름 컬럼에 클러스터형 인덱스를 걸면 내부적으로 다음과 같은 정렬된 인덱스 리스트가 생긴다.
이름 (정렬됨),데이터의 실제 주소 (Pointer)
Apple,3번 페이지의 2번째 줄
Gemini,1번 페이지의 5번째 줄
Zebra,2번 페이지의 1번째 줄
이때 만약 Where 이름='Zebra'라는 쿼리를 날리면 컴퓨터는 원본 데이터를 뒤지는 게 아니라 이 정렬된 리스트(B-tree 구조)를 찾아간다.
1) 이진 탐색: 리스트가 알파벳 순서대로 정렬되어 있기 때문에, 이진 탐색한다.
2) 주소 확인: 'Zebra'옆에 적힌 주소를 확인한다.
3) 데이터 인출: 그 주소로 바로 점프해서 나머지 데이터를 가져온다.
인덱스가 정렬 상태를 유지하기 때문에 새로운 데이터가 들어오면 골치 아파진다.
인덱스 리스트의 맨 뒤에 그냥 추가하는 것이 아니라 적절한 위치에 사이를 비집고 들어가서 순서를 다시 맞춰야 한다. 따라서 인덱스가 많아지면 데이터를 넣거나 수정하 때 속도가 느려진다.
2개 이상의 컬럼을 묶어서 하나의 인덱스로 만들어 쿼리 조건에 딱 맞는 전용 인덱스를 사용할 수 있다.
만약 복합인덱스를 (이름, 카테고리) 이렇게 설정했다면 쿼리에서 순서가 매우 중요하다. 인덱스가 이름->카테고리로 적혀있는데, 만약 WHERE 카테고리='중식'으로 쿼리가 작성되어 있으면 인덱스는 작동하지 않는다.
- 복합 인덱스 설정: (이름, 카테고리) 순으로 생성함
- 쿼리 A: WHERE 이름='xxx' AND 카테고리='중식' (작동 OK)
- 쿼리 B: WHERE 카테고리='중식' AND 이름='xxx' (작동 OK - 옵티마이저가 순서 바꿈)
복합 인덱스를 만들 때 (이름, 카테고리)로 할지, (카테고리,이름)으로 할지 결정하는 기준은 카디널리티이다. 카디널리티가 높은 것을 앞에 두는게 유리하다.