- 인덱스 튜닝과 설계를 제대로 하기 위해, 인덱스가 수직 탐색, 수평 탐색 단 두 단계만 거친다는 것을 이해하자.
- 인덱스의 기본 구조와 원리에 대해 숙지하자.
- 기본적으로 데이터를 찾는 방법은 두가지이다.
- 테이블 전체를 대상으로 탐색
- 인덱스를 이용.
인덱스를 튜닝할 때 핵심은 두 가지이다.
인덱스 스캔 효율화 튜닝
- 예시
- 이름이 '홍길동' 이고 시력이 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) 저장, 모든 리프 노드는 연결 리스트 형태로 구성됨.
- 각 하위 블록은 해당 값 보다 크거나 같다라는 의미를 갖고 있다.
- B*Tree 구조 :
키 값이 없는 레코드, LMC : LeftMostChild
- 루트, 브랜치 블록이 갖고 있다.
- 하위 블록(자식노드)중 가장 왼쪽의 블록 주소를 갖고 있다.
- 해당 주소에는 키 값을 가진 블록보다 같거나 작은 레코드가 저장되어 있다.
- 루트 블록의 LMC -> '서' 보다 작은 블록 중 가장 왼쪽.
- 강덕승 블록의 LMC -> '강덕승' 보다 작은 블록 중 가장 왼쪽.
ROWID
- 데이터 블록 주소 + 로우 번호
- 데이터 블록 주소
- Data Block Address, DBA
- 테이블 스페이스 내에서 몇번 째 블록 내에 있는 지 알려주는 주소값.
- = 데이터 파일 번호 + 블록 번호
- 로우번호
- 블록 내에서의 순서.
- 데이터 베이스 저장 구조 (복습)
- 블록 : 데이터가 저장되는 단위.
'개발 > TIL' 카테고리의 다른 글
[SQL] 데이터의 저장, 논리적 I/O (0) | 2025.03.10 |
---|---|
[SQL] 복합인덱스를 사용할 때 주의할 점 (0) | 2025.03.07 |
[SQL] spring JPA 에서 자주 등장하는 ':1' 은? (feat 파라미터 바인딩) (0) | 2025.03.06 |
java에서 비동기 처리하기 Mono와 Flux ( reactor.core 라이브러리) (7) | 2025.03.04 |
[SQL 튜닝] SQL 처리과정과 IO (1) | 2025.03.03 |