2022. 1. 4. 16:06ㆍStudy/Database
Part 1. 옵티마이저와 실행계획
1. 옵티마이저
- 실행 계획 : 최적의 실행 방법
- 사용자가 질의한 SQL 문에 대해 최적의 실행 방법을 결정하는 역할
- 다양한 실행 방법들 중에서 최적의 실행 방법을 결정함
- 질의의 수행 속도에 영향을 미침
- 수행해보지 않고 결정해야 함
- 현재는 대부분 비용기반 옵티마이저만 제공
가. 규칙기반 옵티마이저
- 규칙(우선 순위)을 가지고 실행 계획을 생성
- 참조하는 정보 : 인덱스 유무, 연산자 종류, 객체 종류 등
- 15가지 규칙을 기반으로, 우선순위가 높은 순서대로 수행
순위 | 액세스 기법 | 설명 |
1 | Single row by rowid | rowid를 통해서 테이블의 하나의 행 엑세스 |
2 | Single row by cluster join | |
3 | Single row by hash cluster key with unique or primary key |
|
4 | Single row by unique or primary key | 유일 인덱스를 통해서 하나의 행 액세스 |
5 | Cluster join | |
6 | Hash cluster key | |
7 | Indexed cluster key | |
8 | Composite index | 복합 인덱스에 동등 조건(=)으로 검색 |
9 | Single column index | 단일 컬럼 인덱스에 = 조건으로 검색 |
10 | Bounded range search on indexed columns | 인덱스가 생성되어 있는 컬럼에 양쪽 범위를 한정하는 형태로 검색 |
11 | Unbounded range search on indexed columns | 인덱스가 생성되어 있는 컬럼에 한쪽 범위만 한정하는 형태로 검색 |
12 | Sort merge join | |
13 | MAX or MIN of indexed column | |
14 | ORDER BY on indexed column | |
15 | Full table scan | 전체 테이블 액세스 |
- Join 시, join column 에 대한 index 유무가 중요함
Join 기법 | A 테이블 | B 테이블 | 설명 |
Sort Merge Join |
index 있음 | index 있음 | 우선순위대로 결정 |
index 있음 | index 없음 | B 테이블 ← A 테이블 JOIN (index 가 없는 테이블이 선행 테이블) | |
index 없음 | index 있음 | A 테이블 ← B 테이블 JOIN (index 가 없는 테이블이 선행 테이블) | |
NL Join | index 없음 | index 없음 | FROM 절 뒤에 나열된 테이블을 선행 테이블로 선택 (우선순위가 동일하다면, 뒤에서부터 역순으로 선행 테이블 선택) |
나. 비용기반 옵티마이저
- 필요한 비용이 가장 적은 실행계획을 선택
- 테이블, 인덱스 ,컬럼 등 다양한 객체 통계정보, 시스템 통계정보 등을 이용함 → 정확한 통계정보 유지 필요
비용 이란?
- SQL문을 처리하기 위해 예상되는 소요시간, 자원 사용량
- 비용기반 옵티마이저 구성 요소
모듈 | 설명 |
질의 변환기 | 사용자가 작성한 SQL 문을 처리하기 용이한 형태로 변환 |
대안 계획 생성기 | 동일한 결과를 내는 다양한 대안 계획을 생성 (연산의 적용 순서 변경, 연산 방법 변경, 조인순서 변경 등) |
비용 예측기 | 대안 계획의 비용을 예측 (연산의 중간 집합 크기, 결과 집합 크기, 분포도 등 예측이 정확해야 함) |
- 실행계획의 예측 및 제어가 어려움
2. 실행계획
- SQL 에서 요구한 사항을 처리하기 위한 절차와 방법
- 어떤 순서로 어떻게 실행할 지를 결정하는 작업
- 구성 요소
요소 | 설명 |
조인 순서 | 조인작업을 수행할 때 참조하는 테이블의 순서, n! 개 만큼 존재 |
조인 기법 | 두 개의 테이블을 조인할 때 사용할 수 있는 방법 (NL Join, Hash Join, Sort Merge Join 등) |
액세스 기법 | 하나의 테이블을 액세스할 때 사용할 수 있는 방법 (Index Scan, Full Table Scan 등) |
최적화 정보 | 예상되는 비용 사항을 표시한 것, 옵티마이저가 계산한 예상치 - Cost : 상대적인 비용 - Card(inality) : 주어진 조건을 만족한 결과집합 건수 - Bytes : 결과 집합이 차지하는 메모리 양 |
연산 | 여러 가지 조작을 통해서 원하는 결과를 얻어내는 일련의 작업 (Join, Scan, 필터, 정렬, 집계 뷰 등) |
3. SQL 처리 흐름도
- SQL의 내부적인 처리 절차를 시각적으로 표현한 도표
- 실행계획을 시각화한 것
- 일량을 함께 표시할 수 있음
Part 2. 인덱스 기본
1. 인덱스 특징과 종류
- 원하는 데이터를 쉽게 찾을 수 있도록 도움
- 테이블을 기반으로 선택적으로 생성할 수 있는 구조
- 검색 성능 최적화를 위함
- DML 작업은 테이블과 함께 인덱스도 변경해야 하므로 느려질 수 있음
가. 트리 기반 인덱스
- B-Tree Index
- Branch Block 과 Leaf Block 으로 구성
Block | 설명 |
Branch Block | - Root Block : 가장 상위에 있는 블록 - 분기를 목적으로 하는 블록 - 다음 단계의 블록을 가리키는 포인터를 가짐 |
Leaf Block | - 가장 아래 단계에 존재하는 블록 - 인덱스를 구성하는 컬럼의 데이터와 해당 데이터를 가지고 있는 행의 위치를 가리키는 레코드 식별자로 구성 - 컬럼의 값으로 정렬 - 값이 동일한 경우, 레코드 식별자 순서로 저장 - 양방향 링크를 가지고 있음 (오름차순, 내림차순 검색을 쉽게 함) |
- 일치검색, 범위검색 모두에 적합
- 동일 컬럼으로 구성된 인덱스를 중복 생성 불가, 단, 순서가 다르면 가능
- 검색 과정
1) 찾을 값 ≤ Branch Block 가장 왼쪽 값 → 왼쪽 포인터로 이동
2) Branch Block 왼쪽 값 < 찾을 값 ≤ Branch Block 가운데 값 → 가운데 포인터로 이동
3) Branch Block 가장 오른쪽 값 < 찾을 값 → 오른쪽 포인터로 이동
나. SQL Server 의 클러스터형 인덱스
- 저장 구조에 따라 클러스터형 인덱스, 비클러스터형 인덱스로 나뉨
- 클러스터형 인덱스 특징
1) 인덱스 리프 페이지 = 데이터 페이지
• 테이블 탐색에 필요한 레코드 식별자가 리프 페이지에 없음
• 인덱스 키 컬럼, 나머지 컬럼을 리프페이지에 같이 저장하므로 테이블에 랜덤 액세스 할 필요 없음
• 해당 테이블의 모든 컬럼 값을 바로 얻을 수 있음
2) 리프 페이지의 모든 데이터(Row)는 인덱스 키 컬럼 순으로 물리적으로 정렬되어 저장
• 물리적으로 한 가지 순서로만 정렬될 수 있음
• 테이블 당 1개만 생성 가능
2. 전체 테이블 스캔과 인덱스 스캔
가. 전체 테이블 스캔
- 테이블에 존재하는 모든 데이터를 읽어서 필요한 결과 추출
- Oracle : 테이블의 고수위 마크(High Water Mark) 아래의 모든 블록을 읽음
- HWM : 테이블에 데이터가 쓰여졌던 블록 상의 최상위 위치 (현재는 데이터가 없을 수 있음)
- 모든 결과를 찾을 때까지 오래 걸릴 수 있음
전체 스캔을 하는 이유?
- SQL 문에 조건이 없는 경우
- SQL 문의 조건에 인덱스가 존재하지 않는 경우
- 옵티마이저의 취사 선택
- 병렬처리 또는 힌트를 사용한 경우 등
나. 인덱스 스캔
- 인덱스를 구성하는 컬럼의 값을 기반으로 데이터를 추출
- 인덱스에 존재하지 않는 컬럼의 값이 필요한 경우, 현재 읽은 레코드 식별자를 이용하여 테이블 액세스
- 인덱스를 경유하기 때문에 결과도 정렬되어 반환됨
스캔 방법 | 설명 |
인덱스 유일 스캔 | Unique Index 를 사용하여 단 하나의 데이터 추출, = 로 주어진 경우 |
인덱스 범위 스캔 | 한 건 이상의 데이터를 추출 (비유일 인덱스 사용) |
인덱스 역순 범위 스캔 | 인덱스의 리프 블록의 양방향 링크를 이용하여 내림차순으로 데이터를 읽는 방식 (최대, 최소값 찾기) |
- 인덱스 전체스캔, 인덱스 고속 전체 스캔, 인덱스 스킵 스캔 등
Part 3. 조인 수행 원리
- 두 개 이상의 테이블을 하나의 집합으로 만드는 연산
- 여러 개의 테이블이 조인 되더라도 동시에 수행되지 않음
1. NL Join
- 중첩된 반복문과 유사한 방식으로 조인 수행
- 랜덤 액세스 방식
FOR 선행 테이블 읽음 → 외부 테이블
FOR 후행 테이블 읽음 → 내부 테이블
- 행의 수가 적은 테이블을 조인 순서상 선행 테이블로 선택하는 것이 유리
NL Join 작업 방법?
- 선행 테이블에서 조건에 해당하는 행 찾음
- 후행 테이블에서 조인 수행 (조인 키 기준)
- 1번에서 찾은 행의 수 만큼 반복
- 추출버퍼 : SQL 문의 실행 결과를 보관하는 버퍼
- 성공하면 바로 조인 결과를 사용자에게 보여줄 수 있음
2. Sort Merge Join
- 데이터를 정렬하여 조인 수행
- 스캔 방식
- 넓은 범위의 데이터를 처리할 때 이용
- 정렬할 데이터가 많은 경우, 임시영역을 사용하기 때문에 성능이 떨어질 수 있음
- 비동등 조인에 대해서도 조인 작업이 가능
- 조인 컬럼의 인덱스가 존재하지 않을 경우에도 사용할 수 있음
- 일반적으로 대량의 조인은 Hash Join 이 유리
Sort Merge Join 작업 방법?
- 선행 테이블에서 조건에 해당하는 행 찾음
- 선행 테이블에서 정렬 작업 수행 (조인 키 기준)
- 조건을 만족하는 선행 테이블의 모든 행에 대해 1~2 반복
- 후행 테이블에서 조건에 해당하는 행 찾음
- 후행 테이블에서 정렬 작업 수행 (조인 키 기준)
- 조건을 만족하는 후행 테이블의 모든 행에 대해 4~5 반복
- 조인 수행 후 추출버퍼에 넣음
3. Hash Join
- 해싱 기법을 이용하여 조인 수행
- 서로 동일한 해시 값을 갖는 것들 사이에서 실제 값이 같은지 비교
- NL Join 의 랜덤 액세스 문제 + Sort Merge Join 의 정렬 작업 부담 해결을 위해 사용
- 조인 컬럼의 인덱스가 존재하지 않은 경우에도 사용 가능
- 동등 조인에서만 사용할 수 있음
- 결과 행의 수가 적은 테이블을 선행 테이블로 사용하는 것이 유리
Hash Join 작업 방법?
- 선행 테이블에서 조건에 해당하는 행 찾음
- 선행 테이블의 조인키를 기준으로 해시 테이블 생성
- 조건을 만족하는 선행 테이블의 모든 행에 대해 1~2 반복
- 후행 테이블에서 조건에 해당하는 행 찾음
- 후행 테이블의 조인키를 기준으로 버킷을 찾음 (join 될 때 데이터를 찾음)
- 조인 성공 시 추출버퍼에 넣음
- 조건을 만족하는 후행 테이블의 모든 행에 대해 4~6 반복
'Study > Database' 카테고리의 다른 글
[ADsP] 시험 과목 정리 (0) | 2023.07.24 |
---|---|
[SQLP] 과목 2. SQL 기본 및 활용 - (2) SQL 활용 (0) | 2022.01.04 |
[SQLP] 과목 2. SQL 기본 및 활용 - (1) SQL 기본 (0) | 2021.12.28 |
[SQLP] 과목 1. 데이터 모델링의 이해 - (2) 데이터 모델과 성능 (0) | 2021.12.23 |
[SQLP] 과목 1. 데이터 모델링의 이해 - (1) 데이터 모델링의 이해 (0) | 2021.12.20 |
[SQLP] 시험 과목 정리 (0) | 2021.12.08 |
[SQLP] 이론 7. 백업 및 복구 (0) | 2021.12.08 |
[SQLP] 이론 6. 테이블 설계 (0) | 2021.12.08 |
[SQLP] 이론 5. Transaction (0) | 2021.12.03 |
[SQL] VIEW (0) | 2021.12.03 |