상세 컨텐츠

본문 제목

[친절한 SQL 튜닝] 2장 인덱스 기본

Development Study/SQLP

by yooputer 2024. 10. 11. 08:58

본문

2.1 인덱스 구조 및 탐색

인덱스 튜닝의 두가지 핵심

  • 인덱스 스캔 과정에서 발생하는 비효율을 줄이는 것. 인덱스 스캔 효율화 튜닝
  • 테이블 액세스 횟수를 줄이는 것. 랜덤 액세스 최소화 튜닝

인덱스 구조

  • DBMS는 일반적으로 B*Tree 인덱스 사용
  • 리프블록에 저장된 각 레코드는 키값 순으로 정렬되어 있고, 테이블 레코드를 가리키는 ROWID를 가지고 있음

LMC(Leftmost Child)

  • 키값을 갖지 않는 가장 왼쪽 첫번째 레코드
  • 루트와 브랜치 블록에 존재
  • 키값을 가진 가장 첫번째 레코드를 가리킴

인덱스 탐색 과정

  • 수직적 탐색 : 조건을 만족하는 첫번째 레코드를 찾는다
  • 수평적 탐색 : 찾고자하는 데이터가 더 안나타날때까지 찾는다. 

인덱스 수평적 탐색

  • 수직적 탐색을 통해 스캔 시작점을 찾았으면, 찾고자 하는 데이터가 더 안나타날 때까지 인덱스 리프 블록을 수평적으로 스캔한다. 
  • 인덱스 리프 블록끼리는 서로 앞 뒤 블록에 대한 주소값을 갖는다. 따라서 수평적으로 탐색이 가능하다
  • 수평적 탐색을 통해 얻은 ROWID로 테이블에 액세스한다. 

결합 인덱스 구조

  • 성별, 이름 컬럼으로 인덱스를 생성했다면, WHERE절에서 성별을 먼저 비교하든 이름을 먼저 비교하든 일량에는 차이가 없다. 
    예를 들어 성별이 '여'이고 이름이 '최지우'인 고객을 조회한다면, 성별이 '여'인 고객을 찾고 그 중에서 이름이 '최지우'인 고객을 찾는 것이 아닌 성별이 '여'이고 이름이 '최지우'인 고객을 한번에 찾는다. 

B*Tree

  • B*Tree의 'B'는 'Balanced'의 약자이다
  • 'Balanced'는 어떤 값을 탐색하더라도 인덱스 루트에서 리프 블록에 도달하기까지 읽는 블록 수가 같음을 의미한다. 

2.2 인덱스 기본 사용법

인덱스 사용 조건

  • 인덱스를 사용한다는 것은 리프 블록의 일부만 탐색하는 Range Scan을 하는 것을 의미한다. 
  • 컬럼을 가공하지 않아야 인덱스를 정상적으로 사용할 수 있다. 
    컬럼을 가공하지 않아도 인덱스는 사용 가능하지만, 리프블록 전체를 스캔해야만 한다. 즉, Index Full Scan 방식으로 작동한다. 

인덱스를 Range Scan할 수 없는 이유

  • 인덱스 선두 컬럼이 가공된 경우 ex) substr, nvl, ...
  • LIKE 연산자
  • OR 연산자, in 연산자
  • 인덱스 선두 컬럼이 조건절에 없음

OR Expansion

  • 옵티마이저가 OR 조건식을 union all 형태로 변환하는 것

인덱스를 정말 잘타는지 확인하기

  • 리프블록에서 스캔하는 양 비교하기

인덱스를 이용한 소트연산 생략

  • 인덱스는 정렬이 되어있다. 따라서, 인덱스 컬럼으로 ORDER BY하는 경우 별도로 정렬 연산을 수행하지 않는다. 
  • 내림차순 정렬에서도 인덱스를 사용할 수 있다. 
  • 단, ORDER BY절에서 컬럼을 가공하는 경우 인덱스를 사용한 정렬은 불가능하다. 

2.3 인덱스 확장기능 사용법

인덱스 스캔 방식의 주요 특징

Index Range Scan 리프 블록까지 수직적으로 탐색 후 필요한 범위만 스캔
선두 컬럼을 가공하지 않은 상태로 조건절에 사용해야 함. 
Index Full Scan 수직적 탐색 없이 인덱스 리프 블록을 처음부터 끝까지 수평적으로 탐색하는 방식
인덱스 선두 컬럼이 조건절에 없으면 옵티마이저는 Table Full Scand을 고려하는데, I/O를 줄일 수 있거나 정렬된 결과를 쉽게 얻을 수 있다면 Index Full Scan을 선택한다. 
Index Unique Scan 수직적 탐색만으로 데이터 탐색
'=' 조건으로 탐색하는 경우 선택
Index Skip Scan 루트 또는 브랜치 블록에서 읽은 컬럼 값 정보를 이용해 조건절에 부합하는 레코드를 포함할 가능성이 있는 리프블록만 골라서 액세스하여 탐색
인덱스 선두 컬럼 혹은 중간 컬럼이 조건절에 없어도 인덱스 활용 가능
조건절에 빠진 인덱스 선두 컬럼의 Distinct Value 개수가 적고 후행 컬럼의 Distinct Value 개수가 많을 때 유용
Index Fast Full Scan 논리적인 인덱스 트리 구조를 무시하고 인덱스 세그먼트 전체를 Multiblock I/O 방식으로 스캔
속도는 빠르지만 인덱스 키 순서대로 정렬되지 않는다. 
쿼리에 사용한 컬럼이 모두 인덱스에 포함돼 있을 때만 사용 가능
Index Range Scan 또는 Index Full Scan과 달리, 인덱스가 파티션 돼 있지 않더라도 병렬 쿼리가 가능
병렬 쿼리시 Direct Path I/O 방식을 사용하기 때문에 I/O 속도가 더 빨라짐
Index Range Scan Descending Index Range Scan과 기본적으로 동일한 스캔 방식이나, 인덱스를 뒤에서부터 앞쪽으로 스캔하여 내림차순으로 정렬된다. 

 

'Development Study > SQLP' 카테고리의 다른 글

[친절한 SQL 튜닝] 1장 SQL 처리 과정과 I/O  (0) 2024.10.10

관련글 더보기