인덱스 / B트리

Previous Next


TL;DR




인덱스 Index


단점


INDEX 설계 시 고려할 점



INDEX는 어떻게 동작하는가?

스크린샷 2022-10-13 오전 1 00 00


  1. Index Table에서 where에 포함된 값을 찾음
  2. 해당 컬럼의 인덱스 테이블에 저장된 key-value 값을 참조
  3. 가져온 인덱스 테이블에 저장된 key-value 값으로 원본 테이블에서 값을 조회해옴



INDEX 종류

키에 따른 인덱스 분류

파일 조직에 따른 인덱스 분류



결합 인덱스(다중 컬럼 인덱스)


SELECT * FROM table1 WHERE name='홍길동' AND address='경기도';

예를 들어 위와 같은 쿼리가 있을 때,


결합 인덱스 타는 경우 / 안 타는 경우



ORDER BY 와 GROUP BY에 대한 INDEX

INDEX는 ORDER BY와 GROUP BY에도 영향을 끼치는데 다음과 같은 경우에는 INDEX를 타지 않는다.



인덱스 조회시 주의 사항

범위 조건(LIKE, BETWEEN, <, >)과 INDEX

between, like, <, > 등 범위 조건은 해당 컬럼은 인덱스를 타지만, 그 뒤 인덱스 컬럼들은 인덱스가 사용되지 않습니다.

=, in과 INDEX

컬럼값 가공금지

null 값의 경우

OR 조건




B-Tree, B+Tree

B-Tree

스크린샷 2022-10-12 오후 10 20 14

B-트리는 트리 자료구조의 일종으로 이진트리를 확장해 하나의 노드가 가질 수 있는 자식 노드의 최대 숫자가 2보다 큰 트리 구조. 이진 트리와는 다르게 하나의 노드에 많은 정보를 가질 수 있습니다. 이렇게 하나의 노드에 여러 정보를 담게 되면서 차수라는 개념이 등장합니다.

B-트리 모양의 특징(6가지)

  1. 노드에는 2개 이상의 데이터(key)가 들어갈 수 있으며, 항상 정렬된 상태로 저장된다.
  2. 모든 노드는 최대 M개의 자식을 가진다.
  3. 모든 노드는 키와 자식 노드에 대한 포인터로 이루어져있다.

  4. 특정 노드의 데이터(key)가 K개라면, 자식 노드의 개수는 K+1개여야 한다.

  5. 특정 노드의 왼쪽 서브 트리는 특정 노드의 key 보다 작은 값들로, 오른쪽 서브 트리는 큰 값들로 구성된다.
  6. 노드 내에 데이터는 floor(M/2)-1개부터 최대 M-1개까지 포함될 수 있다

  7. 모든 리프 노드들이 같은 레벨에 존재한다.

    즉, 루트 노드에서 모든 리프 노드로 가는 경로의 길이가 같다.


B-트리 탐색 과정

B-트리는 루트 노드에서 탐색을 시작하여 하향식으로 탐색을 진행한다. 찾고자 하는 값이 K라면 다음과 같은 과정을 거친다.

  1. 루트 노드에서 탐색을 시작한다.
  2. K를 찾았다면 탐색을 종료한다.
  3. K와 노드의 key값을 비교해 알맞은 자식 노드로 내려간다.
  4. 해당 과정을 리프 노드에 도달할 때까지 반복한다.
  5. 리프 노드에서도 K를 찾지 못한다면 트리에 값이 존재하지 않는 것


B-트리 삽입 과정

B-트리에 데이터를 삽입하는 과정은 탐색과는 다르게 상향식으로 진행된다. B-트리에서의 데이터 삽입은 항상 리프 노드에서 시작된다.

  1. 해당원소가 들어 가야 할 리프노드를 찾는다.
  2. 노드에 빈 자리가 있다면 새로운 원소를 삽입한다.
  3. 노드에 빈 자리가 없다면 노드를 2 개로 분할한다.
  4. 기존 노드의 원소와 새로운 원소 중에 중간 값을 분할된 부모 노드의 값으로 한다.
  5. 중간 값보다 작은 값은 왼쪽 노드로 큰 값은 오른쪽 노드에 넣는다
  6. 중간 값을 부모 노드로 넣을 때, 부모 노드에 자리가 없으면 부모 노드도 위의 규칙에 의해 분할한다

적절한 상태? 적절한 상태란, 해당 노드의 데이터 개수가 허용 범위 안에 있는 것을 의미. 반대로 부적절한 상태란 해당 노드의 데이터 개수가 허용 범위를 벗어나 너무 많은 상태를 뜻한다.

B트리 삭제 과정

삭제 과정중에서도 아래와 같은 조건을 만족해야 하며, 조건이 위반되면 트리를 재구조화 한다.

  1. 내부 노드(루트가 아닌 노드)는 M/2 ~ M개의 자식 노드를 가질 수 있다.
  2. 각 노드는 floor(M/2)-1 ~ M-1 개의 데이터(key)를 가질 수 있다.
  3. 노드의 key가 K개 라면 자식 노드의 개수는 K+1개여야 한다.



B+트리

스크린샷 2022-10-13 오전 12 52 55

B+트리란?

B-트리의 특징을 가지고 있지만, 모든 키 값들이 리프 노드에 정렬되어있는 트리 구조 리프 노드를 순차적으로 연결하는 포인터 집합을 가지고 있는 자료 구조(선형 검색 가능)

B+트리 의의

B-트리는 탐색을 위해서 노드를 찾아서 이동해야 한다는 단점을 가지고 있습니다. 이러한 단점을 해소하고자 B+트리는 같은 레벨의 모든 키값들이 정렬되어 있고, 같은 레벨의 Leaf node는 연결리스트 형태로 이어져 있습니다.

스크린샷 2022-10-13 오전 12 47 20

B+트리 장단점

장점

  1. 리프 노드를 제외하고 데이터를 담아두지 않기 때문에 메모리를 더 확보함으로써 더 많은 key를 수용할 수 있다.
    • 하나의 노드에 더 많은 key를 담을 수 있기 때문에 트리의 높이는 더 낮아진다.
    • B+트리의 높이는 B-트리 보다 낮게 구성되므로 검색시간과 디스크에 접근하는 횟수가 줄어든다
  2. 풀 스캔 시, B+트리는 리프 노드에 데이터가 모두 있기 때문에 한 번의 선형탐색만 하면 되기 때문에 B-트리에 비해 빠르다.
    • B-트리의 경우에는 모든 노드를 확인해야 한다.

단점

B-트리와 B+트리 비교

구분 B-트리 B+트리
데이터 저장 리프 노드, 브랜치 노드 모두 데이터 저장 가능 오직 리프 노드에만 데이터 저장 가능
트리의 높이 높음 낮음(한 노드 당 key를 많이 담을 수 있음)
풀 스캔 시, 검색 속도 모든 노드 탐색 리프 노드에서 선형 탐색
키 중복 없음 있음(리프 노드에 모든 데이터가 있기 때문)
검색 자주 access 되는 노드를 루트 노드 가까이 배치할 수 있고, 루트 노드에서 가까울 경우, 브랜치 노드에도 데이터가 존재하기 때문에 빠름 리프 노드까지 가야 데이터 존재
링크드 리스트 없음 리프 노드끼리 링크드 리스트로 연결
공통점 차이점
1. 모든 leaf의 depth가 같다 1. B-트리의 각 노드에서는 key 뿐만 아니라 data도 들어갈 수 있다. 여기서 data는 disk block으로의 포인터가 될 수 있다. B+트리는 각 node에서는 key만 들어가야 한다. 그러므로 B+트리에서는 data는 오직 leaf에만 존재한다.
2. 각 node에는 k/2 ~ k 개의 item이 들어있어야 한다. 2. B+트리는 B-트리와는 달리 add, delete가 leaf에서만 이루어진다.
3. 둘 다 기본적으로 트리 탐색(search) 3. B+트리는 leaf node 끼리 linked list로 연결되어 있다.
4. add시 overflow가 발생하면 split 한다  
5. delete 시 underflow가 발생하면 redistribution하거나 merge 한다.  

조인

물리적인 JOIN

Join이란?

관계형 데이터베이스에서 두 개 이상의 테이블을 연결하여 데이터를 검색하는 방법. 여러 개의 테이블을 하나인 것처럼 활용한다.

Nested-Loop-Join(Join 동작 원리)

4_nestedloop

Table A: Driving Table 혹은 Outer Table이라고 함

Table B: Driven Table 혹은 Inner Table이라고 함

# 등가조인[Equi Join]
# SELECT * FROM 테이블1, 테이블2
#	 WHERE 테이블명1.컬럼명1=테이블명2.컬럼명2;

SELECT E.ENAME, D.DNAME
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
;
  1. Table A에서 row를 하나씩 반복해가며 스캔한다.

  2. Driving Table의

    row 하나 마다
    

    반대편

    Driven Table의 레코드를 하나씩 스캔
    

    해서 Join 조건에 맞으면 데이터를 찾아서 가져온다.

    • 선행 테이블에서 row를 가져온 후 조인 조건절(등가조인이므로 WHERE절)을 검사해서 동일한 조건을 가진 레코드면 후행 테이블에서 가져옴.
  3. 1~2 과정을 Driving Table의 모든 row에 대해 반복

Nested Loop의 실행시간

바로, “Driven Table(Table B)의 조인 키는 인덱스가 걸려 있어야 한다” 임

4_nestedloop2

Row가 적은 Driving Table + Driven Table의 조인키에는 인덱스가 걸려있어야 GOOD

예상질문

##

질문

  1. (몰라서 질문드려요) 기본 인덱스와 클러스터링 인덱스의 차이는 무엇인가요? 보조 인덱스와 언클러스터링 인덱스의 차이는 무엇인가요?
  2. 데이터 갱신시 결합 인덱스는 단일컬럼 인덱스보다 왜 더 비효율적인가요?
  3. Nested Loop의 실행시간을 줄일 수 있는 방법에는 어떤 것이 있을까요?
  4. B+ 트리 꼬리질문
  5. 인덱스 꼬리질문




References