본문 바로가기

자격증/SQLP

1장: 데이터 저장 구조 및 I/O메커니즘

728x90

I/O 튜닝이 곧 SQL 튜닝이라 해도 과언이 아니다.

  • I/O = 잠자는시간
    • I/O가 일어나는 시간동안 프로세스는 잠을 자기 때문
    • I/O가 발생하면 프로세스는 대기큐에서 잠을 잔다. 그리고 I/O가 끝나면 디스패처에 의해 다시 일한다.

시퀀셜 엑세스 vs 랜덤 엑세스

  • 시퀀셜 엑세스
    • 논리적, 물리적으로 연결된 순서에 따라 차례대로 블록을 읽는 방식
  • 랜덤 엑세스
    • 순서를 따르지 않고 레코드 하나를 읽기 위해 한 블록씩 접근하는 방식

논리적 I/O vs 물리적 I/O

  • System Global Area (SGA)
    • DB Buffer Cache, Redo Log Buffer, Shared Pool (Library Cache : SLQ), Data Dictionary Cache
    • 여러 메모리와 사용사 세션이 공유하는 공간
  • DB버퍼캐시
    • 데이터 캐시라고 볼 수 있다. I/O를 통해 얻은 귀중한 데이터를 저장한다.
    • 오라클에서 확인하는 방법 : show sga
  • 논리적 I/O
    • SQL을 처리하는 과정에서 발생한 총 블록 I/O를 말한다. 메모리 I/O가 곧 논리적 I/O이다.
  • 물리적 I/O
    • 실제 디스크에에서 발생한 총 블록 I/O를 말한다.
  • 같은 SQL을 실행했을 때 시간이 달라지는 이유
    • 논리적 I/O는 언제나 일정하다.
    • 그러나 계속 실행할 수록 버퍼에 쌓이는 것이 많아 물리적 I/O가 줄어든다.
  • 그렇기 때문에, 논리적 I/O를 줄임으로서 물리적 I/O를 줄이는 것이 곧 SQL튜닝이다.

Table Full Scan vs Index Range Scan

  • 테이블 풀 스캔 : 모든 데이터 다 읽기
    • 시퀀셜 엑세스와 멀티블록 I/O를 통해 한 블록의 속한 모든 레코드를 한번에 읽고 캐시에서 못찾으면 한번의 I/O를 통해 다음 수십 수백개의 블록을 한번에 가져온다.
    • 소량의 데이터를 찾을 때는 비효율적이어서 반드시 인덱싱을 해야한다.
  • 인덱스 레인지 스캔: 인덱스 사용해서 읽기
    • 인덱스 기반을 사용하면 레코드 하나를 읽기 위해 매번 I/O를 해야하는 메커니즘이다. 그래서 많은 값을 찾을 때는 오히려 풀스캔이 낫다.

캐시 탐색 알고리즘

  • 모든 블록 I/O는 메모리 버퍼 캐시를 경유한다.
  • DBMS는 버퍼캐시를 해시 구조로 관리한다.
    • 0 : 4 → 8 →
    • 1 : 5 → 1
    • 2 : 2
    • 3 : 7 → 11
  • 메모리 공유자원에 대한 엑세스 직렬화
    • 버퍼캐시는 SGA에 포함되므로 모두 공유자원이다. 문제는 하나의 버퍼 블록에 두 개 이상 프로세스가 동시에 접근할 때 일어난다. (Race Condition과 비슷하다) 동시에 접근하면 블록 정합성에 문제가 생길 수 있다.
    • 이를 위해 직렬화(serialization)를 사용한다.
      • 한마디로 표현하면 줄세우기이다.
      • 버퍼 캐시에 대한 동시 접근을 제어하는 저수준의 잠금 메커니즘. 래치는 한 프로세스가 버퍼 블록에 접근하는 동안 다른 프로세스가 동일한 블록을 수정하지 못하도록 한다. 이를 통해 Race Condition을 방지하고 데이터의 정합성을 유지할 수 있다.
    • 버퍼 락
      • 버퍼 캐시의 대한 래치는 원하는 값을 찾았을 때 래치를 푼다. 즉, 다음 프로세스가 캐시에 접근할 수 있다. 그런데 이전에 프로세스도 A블록을 수정중인데 다음 프로세스도 B블록을 수정하려 한다면 정합성에 문제가 생긴다. 그러므로 버퍼락으로 이것을 관리한다.