From f24c2274047a3f7d14462ffd4a81b836e1d3f3af Mon Sep 17 00:00:00 2001 From: YunByungil Date: Mon, 29 Jul 2024 14:02:30 +0900 Subject: [PATCH] =?UTF-8?q?feat:=209=EC=A3=BC=EC=B0=A8=20=EB=8F=85?= =?UTF-8?q?=EC=84=9C=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 9week/byungil.md | 234 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 9week/byungil.md diff --git a/9week/byungil.md b/9week/byungil.md new file mode 100644 index 0000000..a1cf505 --- /dev/null +++ b/9week/byungil.md @@ -0,0 +1,234 @@ +# 7.1 통계 정보와 비용 계산 원리 + +## 7.1.1 선택도와 카디널리티 + +## 선택도와 카디널리티의 관계 + +### 선택도 + +- 전체 레코드 중에서 조건절에 의해 선택되는 레코드 비율 + +### 컬럼 값 종류 개수 (Number of Distinct Value) + +- `=` 조건일 때 + + ``` + 선택도 = 1 / NDV + ``` + + +### 카디널리티 + +``` +카디널리티 = 총 로우 수 * 선택도 = 총 로우 수 / NDV +``` + + + +### 예시 + +> 상품분류 컬럼에 가전, 의류, 식음료, 생활용품 네 개의 값이 존재하고, 전체 레코드가 10만건 +> +- `where 상품분류 = '가전'` 조건절 + - NDV = 4 + - 선택도 = 1 / 4 = 0.25 + - 카디널리티 = 100,000 * 0.25 = 25,000 + +## 옵티마이저와 카디널리티 + +- 옵티마이저는 카디널리티를 계산하고, 그만큼의 데이터를 액세스하는 데 드는 비용을 계산한다. + - 계산한 값을 기반으로 테이블 액세스 방식, 조인 순서, 조인 방식 등을 결정한다. + +### 선택도가 가장 중요 + +- 비용 계산의 시작점이기 때문이다. +- 선택도를 계산할 때 NDV를 사용하므로 이 값을 정확히 구하는 것이 매우 중요하다. +- 통계 정보 수집 주기, 샘플링 비율 등을 잘 결정해야 한다. + +## 7.1.2 통계 정보 + +## 오브젝트 통계 + +### 테이블 통계 + +- 저장된 총 레코드 개수 +- 테이블 블록 수 + - 사용된 익스텐트에 속한 총 블록 수 +- 레코드 당 평균 길이 +- 샘플링한 레코드 수 +- 통계정보 수집 일시 + +### 인덱스 통계 + +- 인덱스 수직적 탐색 비용 계산 + - 브랜치 뎁스 +- 인덱스 수평적 탐색 비용 계산 + - 인덱스 리프 블록 총 개수 + - 인덱스에 저장된 레코드 개수 + - 인덱스의 키와 값의 조합으로 만들 수 있는 값의 개수 + - 인덱스 키 값을 모두 `=` 조건으로 조회할 때 읽게 될 리프 블록 개수 +- 테이블 액세스 비용 계산 + - 인덱스 키 값을 모두 `=` 조건으로 조회할 때 읽게 될 테이블 블록 개수 + - 인덱스 키값 기준으로 테이블 데이터가 모여있는 정도 + +### 컬럼 통계 (히스토그램 포함) + +- 컬럼 값의 종류 개수 (NDV) + - ex: 성별 컬럼의 경우 NDV = 2 +- `=` 조건으로 검색할 때의 선택도를 미리 구해 놓은 값 (`1/NDV`) +- 컬럼 평균 길이 +- 최소 값 +- 최대 값 +- 값이 NULL인 레코드 수 +- 컬럼 히스토그램 + - 컬럼 값 별로 데이터 비중 또는 빈도를 미리 계산해 놓은 통계 정보 + - 실제 데이터를 읽어서 계산해둔 값 + - 데이터 분포가 많이 변하지 않으면 거의 정확함 + - 사용 이유 + - 선택도를 잘못 구하면 액세스 비용을 잘못 산정하여 최적이 아닌 실행 계획으로 이어짐 + - 데이터 분포가 균일하지 않을수록 잘못 구할 확률이 높아짐 + - 옵티마이저는 데이터 분포가 균일하지 않은 컬럼에 히스토그램을 이용함 + - 타입 + - 도수분포 : 값 별 빈도수 저장 + - 높이 균형 : 각 버킷 높이가 동일하도록 데이터 분포를 관리 + - 상위도수분포 : 많은 레코드를 가진 상위 N개 값에 대한 빈도수 저장 + - 하이브리드 : 도수분포 + 높이균형 + +## 시스템 통계 + +- 애플리케이션 및 하드웨어 성능 특성을 측정한 것 + +### 정보 + +- CPU 속도 +- 평균 Single Block I/O 속도 +- 평균 Multiblock I/O 속도 +- 평균 Multiblock I/O 개수 +- I/O 서브 시스템의 최대 처리량 +- 병렬 Slave의 평균 처리량 + +## 7.1.3 비용 계산 + +- 인덱스 통계, 유효 인덱스 선택도, 유효 테이블 선택도 등의 정보를 이용하여 계산 + +## 비용 모델 + +### I/O 비용 모델 + +- 비용 = 예상 I/O Call 횟수를 의미 + +### CPU 비용 모델 + +- 비용 = Single Block I/O를 기준으로 한 상대적 시간을 의미 +- 같은 실행계획으로 같은 양의 데이터를 읽어도, 애플리케이션 및 하드웨어 성능 특성에 따라 절대 소요시간이 달라지기 때문에 CPU 비용 모델을 개발했음 + +# 7.2 옵티마이저에 대한 이해 + +## 7.2.1 옵티마이저 종류 + +## 규칙 기반(Rule-Based) 옵티마이저 + +- 통계 정보를 이용하지 않고, 단순한 규칙에만 의존하여 데이터를 처리 +- 대량 데이터 처리에 부적합 +- 한계 + - 최적의 실행계획 계산에 무리가 있다 (무조건 정해진 대로만 행동) + +## 비용 기반(Cost-Based) 옵티마이저 + +- 규칙 기반 옵티마이저의 한계로 인해 개발된 옵티마이저 + +### 동작 방식 + +1. 사용자 쿼리를 위해 후보군이 될만한 실행 계획들을 도출 +2. 데이터 딕셔너리에 미리 수집해 둔 통계 정보를 이용해 각 실행계획의 예상 비용 산정 +3. 그중 가장 낮은 비용의 실행계획 하나를 선택 + +## 7.2.2 옵티마이저 모드 + +> 목적에 따라 옵티마이저 모드를 잘 설정해야 한다 +> + +## 종류 + +### ALL_ROWS + +- 전체 처리 속도 최적화 + +### FIRST_ROWS(deprecated) + +- 최초 응답 속도 최적화 +- 결과 집합 전체를 읽어야 하는 경우, 전체 수행 속도가 느려질 수 있음 + +### FIRST_ROWS_N + +- 최초 N건 응답 속도 최적화 + +## 옵티마이저에 영향을 미치는 요소 + +- SQL과 연산자 형태 + - SQL을 어떤 형태로 작성했는지 또는 어떤 연산자를 사용했는지 +- 인덱스, IOT, 클러스터, 파티션, MV 등 옵티마이징 팩터 + - 같은 쿼리도 팩터 구성에 따라 실행계획과 성능이 달라짐 +- 제약 설정 + - PK, FK, Check, Not Null 같은 제약들은 무결성을 보장해줄 분만 아니라, 옵티마이저가 쿼리 성능을 최적화하는 데 매우 중요한 메타 정보로 활용됨 +- 통계 정보 + - 잘 작동하던 프로그램이 갑자기 느려진 경우 대부분 통계 정보가 원인임 + - 특정 테이블 통계정보가 갑자기 삭제된 경우 + - 대량 데이터를 지웠다가 다시 입력하기 직전, 데이터가 없는 상태에서 자동으로 통계 정보가 수집된 경우 + - 3년간 갱신하지 않았던 특정 테이블의 통계 정보를 갑자기 재수집 하는 경우 + - 통계 정보 없이 관리하던 테이블에 인덱스를 재생성 하는 경우 +- 옵티마이저 힌트 +- 옵티마이저 관련 파라미터 + - 파라미터 추가 또는 기본 값 변경으로 인해 다르게 작동할 수 있음 + +## 옵티마이저의 한계 + +- 옵티마이저도 실수를 한다 + - 옵티마이저의 선택은 항상 최선인 것은 아니다 +- 통계 정보를 필요한 만큼 충분히 확보하는 것은 불가능하다 +- 기본적으로 비용 기반이나, 내부적으로 여러 가정과 정해진 규칙을 통해 기계적인 선택을 한다 + - 판단이 애매할 경우 규칙들이 오히려 현실에 안맞을 수 있다 +- 최적화에 허용되는 시간이 매우 짧다 + +## 개발자의 역할 + +- 개발자 스스로가 옵티마이저가 되어야 한다 +- 결과물이 올바른지 실행계획을 통해 늘 점검하고 개선 포인트가 없는지를 찾으려 노력하자 +- 필요한 최소 블록만 읽도록 쿼리를 작성하자 + - 결과 집합을 논리적으로 잘 정의하고, DB 프로세스가 최소한의 일만 하도록 효율적인 쿼리를 작성해야 한다 (I/O 효율을 증가시키자!) +- 최적의 옵티마이징 팩터를 제공하자 + - 옵티마이저가 최적화를 잘 수행하도록 적절한 수단을 제공하자 + - 옵티마이징 팩터 + - 전략적인 인덱스 구성 + - DBMS가 제공하는 다양한 기능 활용 + - 적절한 옵티마이저 모드 설정 + - 정확하고 안정적인 통계 정보 +- 필요하다면, 옵티마이저 힌트를 통해 최적의 액세스 경로로 유도하자 + +## 데이터베이스 튜닝 + +### SQL 튜닝 + +- I/O 효율화 +- DB Call 최소화 +- SQL 파싱 최소화 + +### DB 설계 + +- 논리적 데이터 구조 설계 +- 물리적 저장 구조 설계 + +### 인스턴스 튜닝 + +- Lock/Latch 모니터링 및 해소 +- 메모리 설정 +- 프로세스 설정 \ No newline at end of file