2.3 장
개념적인 튜닝 용어
1) 기초 용어
2) 응용 용어
- 테이블 스캔 : 인덱스 거치지 않고 바로 디스크에 위치한 테이블 데이터에 접근
- 테이블 풀 스캔- 인덱스 스캔 : 인덱스로 테이블 데이터에 접근
- 인덱스 범위 스캔/인덱스 풀 스캔/인덱스 고유 스캔/인덱스 루스 스캔/인덱스 병합 스캔
1) 테이블 풀 스캔

2) 인덱스 범위 스캔

3) 인덱스 풀 스캔

4) 인덱스 고유 스캔

5) 인덱스 루스 스캔

6) 인덱스 병합 스캔

데이터 검색을 위해 저장된 스토리지의 페이지(데이터를 검색하는 최소 단위로, 페이지 단위로 데이터 R/W 가능)에 접근
- 시퀀셜 액섹스 : 서로 연결된 페이지를 차례로 읽음
- 랜덤 액세스 : 여기저기 원하는 페이지를 임의로 열어보면서 데이터 읽음
1) 시퀀셜 액세스

2) 랜덤 액세스

where 조건문 기분으로 데이터가 저장된 디스크에 접근
=> 이때 필요한 데이터에 액세스하는 조건문으로 데이터 가져옴 (액세스 조건)
=> 가져온 데이터에서 다시 한번 출력할 데이터만 추출 (필터 조건)
1) 액세스 조건
디스크에 어떻게 접근할 것인지를 다루는 액세스 조건
< 옵티마이저 역할 >
- where 절의 특정 조건문을 이용해 소량의 데이터 가져옴
- 인덱스 통해 시간 낭비 줄이는 조건절 선택
- 스토리지 엔진의 데이터에 접근
- MySQL 엔진으로 데이터 가져옴
액세스 조건 예제)
- where 절에 ID=1 과 CODE='A' 존재하지만, ID 열로 생성된 인덱스(Table2_index) 를 활용해서 TABLE2 테이블의 일부 데이터에 접근
- 즉, ID=1 조건문이 액세스 조건
- 만약, CODE='A' 조건문을 액세스 조건으로 삼아 데이터에 접근한다면 인덱스 활용없이 대량의 데이터에 접근

2) 필터 조건
엑세스 조건을 사용해 MySQL 엔진으로 가져온 데이터를 기준으로 추가로 불필요한 데이터를 제거하거나 가공하는 필터 조건
필터 조건 예제)
- 액세스 조건으로 가져온 데이터를 대상으로 필터조건인 CODE='A'를 적용해 필터링 작업 진행
필터링할 데이터가 없으면 => GOOD SQL
필터링되어 제거된 데이터 다수 존재하면 => BAD SQL

선택도 예제 )
학생 테이블 데이터 100건 (학번,이름,성별)
1000 이라는 학번을 가진 선택
학번 열의 선택도 = 선택한 데이터 건수 / 전체 데이터 건수 = 1 / DISTINCT(COUNT 학번) = 1 / 100 = 0.01
성별='여' 조건을 가진 선택
성별 열의 선택도 = 선택한 데이터 건수 / 전체 데이터 건수 = 1 / DISTINCT(COUNT 열명) = 50 / 100 = 1 / 2 = 0/5
카디널리티 예제 )
학생 테이블 데이터 100건 (학번,이름,성별)
1000 이라는 학번을 가진 선택
학번 열의 선택도 = 선택한 데이터 건수 / 전체 데이터 건수 = 1 / DISTINCT(COUNT 학번) = 1 / 100 = 0.01
학번 열의 카디널리티 = 전체 데이터 건수 선택도 = 100 0.01 = 1
모든 학번의 데이터값이 고유한 만큼 1건의 데이터만 출력되리라 예측
MySQL에서 카디널리티란??
MySQL 은 중복을 제외한 유일한 데이터값의 수로 계산합니다. 따라서 특정 열에 중복된 값이 많다면 카디널리티는 낮고, 해당 열을 조회하면 많은 수의 데이터를 거르지 못한 채 대량의 데이터가 출력된다고 예측합니다. 반대로 특정 열에 중복된 값이 적으면 카디널리티는 높고, 해당 열을 조회하면 많은 수의 데이터를 거르고 소수의 데이터만 출력된다고 예측합니다.
카디널리티가 높은 것 : 주민등록번호, 휴대폰 번호, 계좌 번호
카니널리티가 중간인 것 : 이름
카디널리티가 낮은 것 : 성별, 졸업여부
select 학번,전공코드
from 학생 /*! USE INDEX (학생_IDX01) */
where 이름='유재석';
select 학번,전공코드
from 학생 USE INDEX (학생_IDX01)
where 이름='유재석';
select 학번,전공코드
from 학생 USE INDEX (학생_IDX01)
where 이름='유재석';
# 다음날, 옵티마이저가 불필요한 인덱스라고 판단하고 삭제
ALTER TABLE 학생 DROP_INDEX 학생_IDX01;
# 인덱스 삭제됐으므로 오류 발생
select 학번,전공코드
from 학생 USE INDEX (학생_IDX01)
where 이름='유재석';
=> ERROR ...


캐릭터셋 vs 콜레이션
테이블 통계정보/인덱스 통계정보/선택적인 열 통계정보 를 토대로 어떤 인덱스를 활용해 데이터에 액세스하고 어떤 테이블을 드라이빙 테이블로 선택할지 등을 결정 => 통계정보의 최신성 유지 및 관리가 매우 중요
실제 데이터베이스에서 관리하는 히스토그램의 버킷은 최댓값을 보관
where 절 조건문에Col1='A'->버킷 1에만 접근해 데이터 분포 파악
where 절 조건문에Col1 BETWEEN E AND O->버킷 2~버킷 6까지 접근 -> 50%이상의 영역을 스캔해야하므로 인덱스 스캔보다 테이블 풀스캔을 추천