[ 튜닝 ] 통계
= 테이블의 데이터 분포를 기반으로 계산된 정보
데이터 고유 값 수를 포함하기에 조회 대상 데이터의 예상되는 행 수를 산정하는데 사용한다
→ 있을 때 Merge join, 없을 때 Hash join으로 성능차이가 있다
* Merge join : Join 입력이 작지 않지만 Join 열을 (인덱스로부터 미리) 정렬된 상태로 가져올 수 있는 경우 가장 빠른 방법
* Hash join : Join 입력의 크기가 크고 정렬되지 않았으며 인덱싱되지 않은 입력을 효율적으로 처리
통계 구성
헤더, 밀도벡터, 히스토그램으로 구성되어있다
DBCC SHOW_STATISTICS ([tableName], [idex_Name])
3개의 결과물이 select되는데 헤더, 밀도벡터, 히스토그램 순서이다
1) 통계 헤더 : 대상 통계에 대한 기본 정보만 제공
2) 밀도 벡터 : 단일 열 혹은 인덱스에 포함된 모든 열에 대한 선택도를 나타낸다
* 선택도 : 특정 조건에 의해서 선택될 것이라 예상되는 비율
선택도가 높으면 좋지 않다 → 행 수를 예상하여 더 많은 RID LOOK을 소요할 수 도 있다
3) 히스토그램 : 통계 개체의 첫 번째 키 열에 있는 데이터 분포를 나타낸다
열 값을 정렬시키고 최대 200개 단위로 끊어 집계한다
예) key 1~200까지 , 200~400까지..
select시 예상 행 건 수가 필요한데 히스토그램의 AVG_RANGE_ROWS를 이용한다
바인드 변수 활용
= 바인드 변수 사용 시 실행 계획 생성할 때 변수 실제값을 알 수 없어 히스토그램을 사용할 수 없기에 밀도 벡터를 사용한 카디널리티 계산을 한다 → 부정확한 예상 행을 참조함
* 바인드 변수 : parameter로 넘겨지는 값 → @num
* 리터럴 변수 : 비교되는 값이 상수값으로 직접 선언된 경우의 변수
1) 리터럴 변수를 사용할 때
select * from table where productNumber = 2000
히스토그램 통계를 참조하여 정확한 행 수로 실행 계획을 생성한다
2) 등치 조건의( = ) 바인드 변수를 사용할 때
declare @productNumber int
set @productNumber = 2000
select * from table where productNumber = @productNumber
밀도 벡터의 선택도 * 전체 행수 로 예상 행 수를 실행 계획으로 생성한다
3) 등치 조건이 아닌 ( >,< ) 바인드 변수를 사용할 때
declare @productNumber int
set @productNumber = 2000
select * from table where productNumber >= @productNumber
전체 행 수 * 0.3 로 예상 행 수를 실행 계획으로 생성한다
4) 동적쿼리 실행 시
declare @productNumber NVARCHAR(100)
declare @SQL NVARCHAR(100)
set @productNumber = 2000
set @SQL = 'select * from table where productNumber >=' + @productNumber
exec @SQL
히스토그램 통계를 참조하는 것으로 보아 실제 값을 대입 후 컴파일 함을 알 수 있다
자동 통계
1) 자동 통계 작성 : SQL 구문에 조건절로 사용된 열에 기본 통계가 없을 때 내부적으로 통계를 생성해주는 옵션
- 데이터베이스 통계 옵션이 true일 때
index 통계 : 테이블 생성 시 생성되는 통계
열 통계 : 테이블 당 통계 부분이 존재하여 select 컴파일 할 때마다 자동 생성된다
정적 임계치 사용 : 데이터수가 임계치에 도달해도 통계 정보가 바뀌지 않는다
동적 임계치 사용 : 데이터 양에 따라 임계치가 달라진다
* 임계치 : 어떠한 물리현상이 다르게 나타나는 경계의 값