ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • InnoDB 인덱스와 클러스터링 인덱스
    책/Real MySql 2021. 5. 26. 16:52

    InnoDB는 MySQL의 저장 엔진 중 하나로, 높은 성능과 데이터 무결성을 제공한다.  InnoDB의 인덱스 구조와 클러스터링 인덱스에 대해 알아보자.

     

    InnoDB 인덱스 구조

    InnoDB에서 인덱스는 B-tree 구조를 사용한다. B-tree는 데이터베이스 인덱싱에서 널리 사용되는 구조로, 데이터를 정렬된 상태로 유지하고 검색, 삽입, 삭제 작업을 효율적으로 수행할 수 있도록 돕는다.

    B-tree 인덱스

    B-tree 인덱스는 여러 노드로 구성되며, 각 노드는 다음과 같은 구성 요소를 포함한다:

    • 루트 노드(Root Node): 트리의 최상위 노드로, 데이터베이스가 인덱스 검색을 시작하는 지점이다.
    • 내부 노드(Internal Node): 루트 노드와 리프 노드 사이에 위치한 노드로, 자식 노드로의 포인터를 포함한다.
    • 리프 노드(Leaf Node): 트리의 최하위 노드로, 실제 데이터 페이지에 대한 포인터와 인덱스 키 값을 포함한다.

    B-tree 인덱스는 균형 잡힌 트리 구조를 유지하며, 모든 리프 노드는 동일한 깊이에 위치한다. 이를 통해 검색, 삽입, 삭제 작업이 항상 일정한 시간 내에 수행될 수 있다.

     

     

    Index Full Scan?

    인덱스 풀 스캔(Full Index Scan)은 B-tree 인덱스의 모든 노드를 읽는 과정을 포함한다. 이는 루트 노드, 내부 노드, 그리고 리프 노드를 모두 포함한다.

    인덱스 풀 스캔의 과정은 다음과 같다:

    1. 루트 노드 읽기: 루트 노드에서 시작하여, 트리의 최상위에서부터 아래로 내려가면서 모든 노드를 순차적으로 스캔.
    2. 내부 노드 읽기: 루트 노드 아래의 내부 노드를 순차적으로 읽는다.
    3. 리프 노드 읽기: 최종적으로 리프 노드를 읽어, 인덱스에 저장된 실제 데이터 페이지의 위치 정보를 얻는다. ( inno DB의 경우 프라이머리 키를 위치 정보로 얻음 )

    풀 스캔은 모든 노드를 읽어들이는 과정이기 때문에, 리프 노드를 포함하여 전체 B-tree를 순차적으로 탐색하게 된다. 인덱스 풀 스캔을 통해 데이터베이스는 인덱스의 모든 엔트리를 읽어 필요한 데이터를 찾는다.

     

    이 과정은 다음과 같은 이유로 수행될 수 있다:

    • 특정 쿼리가 인덱스의 모든 엔트리를 검사해야 하는 경우 (예: 인덱스에 대한 범위 조건이 없거나 전체 인덱스를 확인해야 하는 경우).
    • 통계 정보를 수집하기 위해 인덱스를 스캔하는 경우.

    따라서 인덱스 풀 스캔은 루트 노드와 내부 노드뿐만 아니라 리프 노드도 포함하여 전체 B-tree 구조를 모두 읽는 작업을 의미한다.

     

     

    테이블과 인덱스?

    1. 테이블과 인덱스:
      • 테이블: 실제 데이터가 저장된 곳이다.
      • 인덱스: 특정 컬럼의 값을 기반으로 데이터의 위치를 빠르게 찾기 위한 구조이다. 인덱스는 B-tree 구조로 저장되며, 인덱스 테이블이라고 할 수 있다.
    2. 풀 테이블 스캔:
      • 풀 테이블 스캔: 테이블에 저장된 모든 데이터를 읽는 과정이다. 인덱스를 사용하지 않고, 테이블의 모든 행을 읽어 필요한 데이터를 찾는다.
    3. 풀 인덱스 스캔:
      • 풀 인덱스 스캔: 인덱스의 모든 노드를 읽는 과정이다. 루트 노드부터 리프 노드까지 인덱스의 모든 엔트리를 순차적으로 스캔한다.
    4. 전체 스캔 과정:
      • 인덱스 풀 스캔: 인덱스 테이블의 모든 노드를 읽어 인덱스에 저장된 데이터의 위치 정보를 얻는다.
      • 데이터 접근: 인덱스 테이블의 리프 노드에 저장된 실제 데이터 페이지의 주소를 통해 디스크에서 해당 데이터를 읽어온다.

    따라서 인덱스 풀 스캔은 인덱스 테이블을 통해 모든 인덱스 엔트리를 읽고, 필요한 경우 리프 노드에 저장된 주소를 통해 실제 데이터 페이지를 접근하는 과정이다. 이로 인해 인덱스 풀 스캔은 루트 노드와 내부 노드뿐만 아니라 리프 노드도 모두 포함하여 인덱스의 모든 엔트리를 탐색하게 된다.

    풀 테이블 스캔과 인덱스 풀 스캔은 각기 다른 용도로 사용되며, 특정 쿼리에 따라 선택적으로 수행된다.

     

     

    클러스터링 인덱스

    InnoDB의 가장 중요한 인덱스는 클러스터링 인덱스다. 클러스터링 인덱스는 테이블의 프라이머리 키를 기준으로 데이터가 물리적으로 정렬되어 저장되는 구조를 말한다. 이는 데이터 접근 성능을 최적화하는 데 큰 도움이 된다.

    클러스터링 인덱스의 특징

    1. 프라이머리 키 정렬: 클러스터링 인덱스는 프라이머리 키 값을 기준으로 데이터를 정렬한다. 따라서 프라이머리 키를 기준으로 데이터를 검색할 때 매우 효율적이다.
    2. 데이터 페이지에 직접 접근: 클러스터링 인덱스의 리프 노드는 실제 데이터 페이지를 가리키며, 이를 통해 데이터를 직접 읽을 수 있다.
    3. 한 개의 클러스터링 인덱스: 각 테이블에는 하나의 클러스터링 인덱스만 존재할 수 있다. 보통 프라이머리 키가 클러스터링 인덱스로 설정된다.

    클러스터링 인덱스의 장점

    • 빠른 범위 쿼리: 프라이머리 키의 범위 내에서 데이터를 검색할 때, 데이터가 물리적으로 연속된 위치에 저장되므로 디스크 I/O가 최소화된다.
    • 효율적인 데이터 접근: 데이터가 프라이머리 키 순서대로 정렬되어 있어, 특정 키 값으로 데이터를 검색할 때 빠르게 접근할 수 있다.

    클러스터링 인덱스의 단점

    • 데이터 재정렬: 프라이머리 키를 기준으로 데이터를 정렬하기 때문에, 삽입, 업데이트, 삭제 작업 시 데이터 페이지가 재정렬될 수 있다. 이는 추가적인 오버헤드를 발생시킬 수 있다.
    • 프라이머리 키 크기 영향: 프라이머리 키가 클수록 클러스터링 인덱스의 크기도 커지므로, 작은 프라이머리 키를 사용하는 것이 좋다.

     

    인덱스 탐색의 랜덤 IO

    1. 트리 구조 탐색: B-tree 구조의 인덱스는 루트 노드에서 시작해 내부 노드를 거쳐 리프 노드에 도달하는 트리 형태로 되어 있다. SSD에서도 각 노드는 물리적으로 비연속적으로 저장될 수 있다.
    2. 비연속적 접근: 인덱스를 통해 데이터에 접근할 때, 노드들이 논리적으로 연결되어 있지만 물리적으로는 비연속적으로 배치되어 있을 가능성이 크다.
    3. 리프 노드와 데이터 페이지: 리프 노드가 실제 데이터 페이지의 주소를 가리키고 있지만, 이 데이터 페이지들도 물리적으로 비연속적으로 저장될 수 있다. 따라서 데이터 접근 시 랜덤 IO가 발생할 수 있다.

    테이블 풀 스캔의 순차 IO

    1. 연속적인 페이지 접근: 테이블 풀 스캔은 테이블의 모든 데이터를 처음부터 끝까지 읽는다. 데이터 페이지들이 논리적으로 연속적으로 읽히기 때문에, 순차적으로 접근하는 방식이다.

    예외 사항

    • 데이터 조각화: 테이블에 빈번한 삽입, 삭제, 업데이트가 발생하면 데이터가 조각화되어 디스크 상에 비연속적으로 저장될 수 있다. 이 경우 테이블 풀 스캔이 순차 IO 대신 랜덤 IO를 수행해야 할 수도 있음.
    • 대규모 데이터베이스: 매우 큰 데이터베이스의 경우, 데이터 페이지들이 완벽하게 연속적으로 저장되지 않을 수 있다. 하지만 일반적으로 데이터베이스 시스템은 가능한 한 데이터 페이지를 연속적으로 저장하려 한다.

     

    순차 IO와 클러스터링 인덱스: 클러스터링 인덱스는 데이터가 논리적으로 연속적으로 저장되도록 하여, 순차 IO를 가능하게 하고 성능을 향상시킨다. 

Designed by Tistory.