개발/TIL

[SQL] 인덱스 기본 구조

ebang 2025. 3. 9. 00:29
  • 인덱스 튜닝과 설계를 제대로 하기 위해, 인덱스가 수직 탐색, 수평 탐색 단 두 단계만 거친다는 것을 이해하자.
  • 인덱스의 기본 구조와 원리에 대해 숙지하자.

  • 기본적으로 데이터를 찾는 방법은 두가지이다.
    • 테이블 전체를 대상으로 탐색
    • 인덱스를 이용.
  • 인덱스를 튜닝할 때 핵심은 두 가지이다.

    • 인덱스 스캔 효율화 튜닝

      • 예시
        • 이름이 '홍길동' 이고 시력이 1.0~2.0 사이인 학생을 찾자!
        • 표 3-2 에서는 이름과 시력 순으로 정렬, 표 3-3에서는 시력과 이름 순으로 정렬
    • 랜덤 엑세스 최소화 튜닝

      • 인덱스 스캔 이후에 테이블 레코드를 엑세스하는 과정은 랜덤 I/O 방식.
      • 테이블 엑세스 횟수 최소화
      • 예시
        • 다시 이름이 '홍길동'이고 시력이 1.0~2.0 인 학생을 찾자!
        • 이름이 '홍길동' 인 학생은 5명, 시력이 1.0~2.0 사이인 학생은 50명이라고 하자.
        • 이름순으로 적힌 학생부, 시력순으로 적힌 학생부가 있을 때, 어떤 학생부에서 찾아야 효율적일까?
      • 성능에 미치는 영향이 더 크다.
  • SQL 튜닝의 핵심은 랜덤 I/O 를 줄이는 데 있다.
    • 데이터베이스 성능은 디스크 I/O 의 영향을 가장 많이 받고, 그 중에서도 랜덤 I/O 가 가장 중요하다고 평가받는다.
    • 데이터베이스에서 개발된 많은 기능들이 이 랜덤 I/O 를 개선하기 위해 등장했다.
      • IOT, 클러스터, 파티션에서부터 테이블 Prefetch, Batch IO

기본적인 I/O 메커니즘과 랜덤 액세스 개념은 1장에서 다뤘다. 랜덤 액세스 최소화를 포함한 인덱스 튜닝은 3장에서 조인 튜닝은 4장에서 다룬다. 그에 앞서 본장은 인덱스 구조와 인덱스 사용법 을 다룬다.

  • 인덱스

    • 학생명부가 없다면, '홍길동'을 찾기위해서 모든 교실을 다 찾아야 할 것.

    • 인덱스가 없다면, 테이블 전체를 모두 찾아야 한다.

    • 이름순으로 정렬된 학생부에서 '홍길동' 다음에 '홍길땡'이 나오면, 탐색을 멈춰도 된다.

    • 인덱스는 범위 탐색이 가능하다. 즉, 정렬되어있다.

  • 인덱스의 구조

    • B*Tree 구조 :
      • 루트 노드(Root Node): 최상위 노드, 검색의 시작점
      • 브랜치 노드(Branch Node): 데이터로 가는 경로 제공 (키와 포인터 저장)
      • 리프 노드(Leaf Node): 실제 데이터의 위치(ROWID) 저장, 모든 리프 노드는 연결 리스트 형태로 구성됨.
      • 각 하위 블록은 해당 값 보다 크거나 같다라는 의미를 갖고 있다.
    • 키 값이 없는 레코드, LMC : LeftMostChild

      • 루트, 브랜치 블록이 갖고 있다.
      • 하위 블록(자식노드)중 가장 왼쪽의 블록 주소를 갖고 있다.
        • 해당 주소에는 키 값을 가진 블록보다 같거나 작은 레코드가 저장되어 있다.
        • 루트 블록의 LMC -> '서' 보다 작은 블록 중 가장 왼쪽.
        • 강덕승 블록의 LMC -> '강덕승' 보다 작은 블록 중 가장 왼쪽.
    • ROWID

      • 데이터 블록 주소 + 로우 번호
      • 데이터 블록 주소
        • Data Block Address, DBA
        • 테이블 스페이스 내에서 몇번 째 블록 내에 있는 지 알려주는 주소값.
        • = 데이터 파일 번호 + 블록 번호
      • 로우번호
        • 블록 내에서의 순서.
      • 데이터 베이스 저장 구조 (복습)
        • 블록 : 데이터가 저장되는 단위.