본문 바로가기

SQL/친절한 sql 튜닝

[3주차] 테이블 액세스 최소화

3.1 테이블 액세스 최소화

 

3.1.1 테이블 랜덤 액세스

 

인덱스를 스캔한 후 반드시 테이블을 액세스(접근)한다

 

인덱스를 스캔하는 이유는

1) 검색 조건을 만족하는 소량의 데이터를 인덱스에서 빨리 찾고,

2) 테이블 레코드를 찾아가기 위한 주소값(RowId)를 얻으려고 한다.

 

RowId는 물리적 주소? 논리적 주소?

물리적 주소: 데이터 파일 번호, 오브젝트 번호, 블록 번호

논리적 주소: 테이블 레코드를 찾아가기 위한 위치 정보를 담은 주소

ex) 도서 색인 : 색인에 기록된 페이지 번호 : RowId

 

 

메인 메모리 DB와 비교

메인 메모리 DB 잘 튜닝된 데이터베이스 시스템
메모리에 데이터를 로드해 놓고
메모리를 통해서 I/O를 수행하는 DB
버퍼캐시 : 메모리에서 데이터 읽기

 

메인 메모리 DB 오라클
인스턴스 가동 ->
디스크에 저장된 데이터를 버퍼 캐시로 로딩 ->
인덱스 생성 ->
인덱스: 디스크 상 주소정보(x),
메모리 상 주소정보(o)(=index Row Id)
포인터를 갖는다
인스턴스 가동 ->
디스크에 저장된 데이터를 버퍼 캐시로 로딩 ->
인덱스 생성 ->
인덱스: 디스크 상 주소정보(O),
메모리 상 주소정보(X)
포인터 없다
해시 알고리즘 ->
버퍼 블록 찾아간다
테이블 접근 비용이 낮다  
  이유
테이블 블록이 수시로 버퍼 캐시에 밀려나다가 다시 캐싱됨.
다른 공간에 캐싱됨.

인덱스 --> 포인터로 바로 연결 안됨.
일반 DBMS에서 인덱스RowId를 이용한 테이블 액세스가 생각만큼 빠르지 않다

 

I/O 메커니즘 복습

 

인덱스를 이용해 테이블 블록 찾기 과정

RowId = 디스크 상에 테이블 레코드를 찾아가기 위한 논리적 주소.

 

1. RowId가 가리키는 테이블 블록을 버퍼캐시에서 찾아본다.

2. 못찾는 경우, 디스크 블록을 읽는다.(블록캑시에 적재한 후에 읽는다)

 

 

블록 읽기

1. RowId가 가리키는 테이블 블록을 버퍼캐시에서 찾아본다.
1) 버퍼캐시 찾는다 
2) 읽고자 하는 DBA를 해시 함수에 입력해서 해시 체인을 찾는다
3) 버퍼 헤더를 찾는다

0) 해싱 알고리즘으로 버퍼 헤더를 찾는다.
1) 버퍼헤드는 항상 같은 해시 체인에 연결된다
2) 실제 데이터가 담긴 버퍼 블록은 매번 다른 위치에 캐싱된다.
3) 그 메모리의 주소값을 버퍼 헤더가 가지고 있다.
4) 얻은 포인터로 버퍼 블록을 찾아간다

 

인덱스 -> 테이블 블록 엑세스

리프 블록에서 읽은 RowId를 분해해서 DBA정보를 얻고

 

테이블 full scan -> extent Map을 통해

읽은 블록들의 DBA 정보를 얻는다.

 

extent map block : 연속적으로 있는 블록을 묶어 둔 것을 의미하는 논리적 단위, 

뭔말이지

 

 

모든 데이터가 캐싱되어 있더라도

테이블 레코드를 찾기 위해

DBA 해싱, 래치획득 과정

반복해야한다.

 

인덱스 RowId를 이용한 테이블 엑세스는 고비용 구조이다. 

 

 

디스크 DB 메인 메모리 DB
RowId 포인터
우편주소 전화번호
일일이 집배원이 하나하나씩 데이터 집에서 찾아간다.
느리다
바로 전화한다. 바로 연결되어있다.
빠르다.

RowId에 의한 테이블 엑세스가 얼마나 고비용인지 봐라

 

 

3.1.1 인덱스 클러스터링 팩터(CF = Cluster Factor)

특정 컬럼을 기준으로

같은 값을 가지는 데이터가

서로 모여 있는 정도

 

 

물리적으로 데이터가 근접해 있으면 흩어져 있을 때보다. 데이터를 찾는 속도가 빠르다.

ex) 분가한 10명의 자녀가 한 동네에 있으면, 부모는 한 지역만 들리면 됨.

하지만 분가한 10명의 자녀가 각자 다른 동네에 살면, 부모는 10 지역을 들려야 함.

 

 

cf 좋은 경우: 3개의 블록에만 접근

인덱스 레코드 정렬 순서

테이블 레코드 정렬 순서가 일치한다.

 

cf 가 나쁜 경우: 6개의 블록에 접근

인덱스 레코드 정렬 순서

테이블 레코드 정렬 순서가 일치하지 않는다.

 

 

 

 

3.1.3 인덱스 손익분기점

인덱스를 쓰면 빠를거 같지? 어느 순간 아니게 된다.

Table Full Scan 보다 느려지는 지점 == 인덱스 손익 분기점이다.

 

 

Table Full Scan 인덱스
시퀸셜 액세스 랜덤 액세스
Multi Block I/O Single Block I/O

 

인덱스를 이용해 테이블 액세스 추출 건수 가 많을 수록 느려진다.

1) 랜덤 액세스

( 랜덤 액세스는 데이터를 저장하는 블록을 한번에 여러 개 액세스하는 것이 아니라 한 번에 하나의 블록만을 액세스하는 방식이다.)

2) 인덱스 스캔량이 증가하면 느려진다

 

 

이를 조취하려면?

온라인 프로그램 튜닝 vs 배치 프로그램 튜닝

온라인 프로그램 튜닝

배치 프로그램 튜닝

소량 데이터 읽고 갱신 대량의 데이터 읽고 갱신
일부 빠르게x
전체를 빠르게o
인덱스, 조인 NL 사용 Full Scan,  해시 조인
빠른 응답  

 

 

소량 데이터: 인덱스, NL 조인

 

 

 

 

 

 

 

 

대량 데이터

 

 

이건 느리다

 

이건 빨라짐
윈도우 함수 사용해서 비효율 삭제

 

결국엔 대량이면 파티션 사용해라.

 

대량 데이터인 경우에는

파티션이 좋다. 

파티셔닝은: full scan을 빠르게 하기 위한 것이다.

'SQL > 친절한 sql 튜닝' 카테고리의 다른 글

[5주차] 소트 머지 조인  (0) 2022.04.17
[4주차] 인덱스 튜닝  (0) 2022.04.10
인덱스  (0) 2022.03.28
[2주차] 인덱스 2.1  (0) 2022.03.27
[1주차]  (0) 2022.03.20