장 소개

\- 불필요하게 많은 SQL 수행, 파싱을 많이 일으키거나, 많은 데이터 Fetch, 많은 I/O일으키도록 구현하는것이 성능문제를 일의키는 90%이상의 요인
\- 데이터 베이스 성능 튜닝의 3대 핵심요소
SQL 파싱 부하 해소, 데이터베이스 Call 최소화, I/O 효율화
\- 성능요소를 해결하는것은 모두 개발팀 역량에 달렸다. 어플리케이션으로부터 발생하는 일량을 근본적으로 줄여야 한다.

장 구성

제1절 데이터베이스 아키텍처 :개괄적인 데이터베이스 아키텍처 설명
제2절 SQL 파싱 부하 : 옵티마이저 최적화 과정설명, 바인드변수사용, 라이버러리 캐시 최적화방법
제3절 데이터베이스 Call과 네트워크 부하 : 데이터베이스 Call횟수줄여 네트워크부하를줄이고 쿼리성능 높이는 방안
제4절 데이터베이스 I/O 원리 : I/O효율화의 세부 원리로서 옵티마이저 원리, 인덱스와 조인 원리

제 1절 데이터베이스 아키텍처

1. 아키텍처 개관

가. Oracle 아키텍쳐

  • 데이터베이스 : 물리적인 디스크에 저장된 데이터 집합 (데이터파일, 리두로그 파일, 컨트롤 파일)
  • 인스턴스 : SGA 공유메모리영역과 이를 액세스하는 프로세스 집합
  • 하나의 인스턴스가 하나의 데이터베이스만 엑세스(Single)
  • 여러인스턴스가 하나의 데이터베이스를 액세스(RAC), 하나의 인스턴스가 여러 데이터베이스를 액세스할 수는 없다.

나. SQL Server 아키텍쳐

  • 하나의 인스턴스당 최고 32,767개의 데이터베이스를 정의해 사용할 수 있다.
  • 시스템 데이터베이스 : master, model, msdb, tempdb
  • 사용자데이터베이스 : 데이터 파일(.mdf) ,트랜잭션 로그 파일(.ldf), 보조데이터 파일(*.ndf)

2. 프로세스

  • SQL Server는 쓰레드로 표현
  • 서버프로세스 : 전면에 나서 사용자가 던지는 각종 명령을 처리
  • 백그라운드 포르세스 : 뒤에서 묵묵히 주어진 역할을 수행

가. 서버 프로세스 (Server Processes)

  • SQL Server는 Worker 쓰레드로 표현
  • SQL파싱 \-> 필요시 최적화 \-> 커서를 열어 SQL실행하면서 블록 Read \-> 읽은데이터를 정렬하여 요청한 결과집합을 만들어 네트워크를 통해 전송
    클라이언트가 서버프로세스와 연결하는 방식(oracle)
1) 전용 서버 (Dedicated Server) 방식
  • 클라이언트언트 세션과 서버프로세스가 1:1 매핑
  • 연결요청 받는 리스너가 서버프로세스(쓰레드)를 생성 \-> 서버프로세스가 단 하나의 사용자 프로세스를 위해 전용(dedicated)서비스 제공

2) 공유 서버 (Shared Server) 방식
  • 클라이언트 세션과 서버프로세스가 1:N 매핑 하나의 서버 프로세스를 여러 사용자 세션이 공유하는 방식

 

나. 백그라운드 프로세스(Background Process)

|| Oracle || SQL Server || 설명 ||

System Monitor

(SMON)
Database cleanup

/Shrinking thread
장애가 발생한 시스템을 재기동할 때 인스턴스 복구를

수행하고, 임시 세그먼트와 익스텐트를 모니터링 한다.
Process Monitor

(PMON)
Open Data Services

(OPS)
이상이 생긴 프로세스가 사용하던 리소스를 복구한다.
Database Writers

(DBWn)
Lazywriter thread버퍼캐시에 있는 Dirty 버퍼를 데이터 파일에 기록한다.
Log Writer(LGWR)Log Writer thread로그버퍼엔트리를 Redo 로그 파일에 기록한다.
Archiver(ArCn)N/A꽉 찬 Redo 로그가 덮어 쓰여지기 전에 Archive 로그디렉토리로 백업한다.
Checkpoint

(CKPT)
Database Checkpoint

thread
Checkpoint 프로세스는 이전에 Checkpoint가 일어났던

마지막 시점 이후의 데이터베이스 변경 사항을 데이터파일

에 기록하도록 트리거링, 기록이 완료되면 현재 어디까지

기록했는지를 컨트롤 파일과 데이터 파일 헤더에 저장.
Recover(RECO)Distributed Transaction

Coordinator(DTC)
분산 트랜잭션 과정에 발생한 문제를 해결한다.

3. 파일구조

가. 데이터 파일

1) 블록(=페이지)
  • 대부분의 DBMS에서는 I/O는 블록 단위로 이루어짐
  • 데이터를 읽고 쓸때 논리적인 단위 \
DB명칭블록크기
ORACLE블록2KB, 4KB, 8KB, 16KB, 32KB, 64KB
SQL Server페이지8KB
2) 익스텐트(Extent)
  • 테이블스페이스로부터 공간을 할당하는 단위 | | 크기 | 오브젝트 |
ORACLE다양한크기의 익스텐트모든블록을 단일오브젝트가 사용
SQL Server항상8개,64KB(page크기가 8KB이므로)2개이상의 오브젝트 사용 가능
  • 균일 (Uniform) 익스텐트 \
64KB 이상의 공간을 필요로 한느 테이블이나 인덱스를 위해 사용되며,


8개 페이지 단위로 할당된 익스텐트를 단일오브젝트가 모두 사용 \
  • 혼합(Mixed) 익스텐트
한 익스텐트에 할당된 8개 페이지를 여러 오브젝트가 나누어 사용하는 형태.

모든 테이블이 처음에는 혼합 익스텐트로 시작하지만 64KB를 넘으면서

2번째부터 균일 익스텐트를 사용하게 된다.
3) 세그먼트

세그먼트(Segment)\

ORACLE세그먼트
SQL Server힙구조 or 인덱스구조오브젝트
  • 테이블, 인덱스 ,undo처럼 저장공간을 필요로한느 데이터베이스 오브젝트
  • table,index는 세그먼트와 1:1관계지만 파티션은 1:M관계(여러개의세그먼트)
  • 한 세그먼트에 할당된 익스텐트가 여러 데이타파일에 흩어져서 저장됨(I/O분산효과)

4) 테이블 스페이스

나. 임시 데이터 파일 (Temp)

ORACLE유저별로 temp tablespace 지정 가능
SQL Servertempdb 데이터베이스를 사용
  • 대량의 정렬이나 해시 작업을 수행하다가 메모리 공간이 부족해 지면 중간 결과 집합을 저장하는 용도
  • 문제 시 복구되지 않음, 백업 불필요


    \

다. 로그 파일(log file)

\-트렌젝션데이터 유실방지


\-마지막 체크포인트이후 사고 발생 직전까지 수행되었던 트랜잭션을 Redo로그를 통해 재현(캐시복구)


\-최소 두개이상의 파일로 구성되며, round-robin방식으로 로그파일 재사용

  • Archived(=Offline) Redo 로그


    \-오라클에서 온라인 리두로그가 재사용 되기 전에 다른 위치로 백업해둔 파일


    \-디스크가 깨지는 등의 물리적인 저장매체 장애에 대해 복구하기 위해 사용
  • Sql server 트랜잭션 로그


    \-데이터베이스마다 트랜잭션 로그 파일이 하나씩 생김(*.ldf)


    \-가상로그파일이라불리는 더 작은 세그먼트 단위로 나뉨


    \-가상로그파일 개수가 너무 많아지지 않도록 옵션을 지정(ex)로그파일을 애초에 넉넉한 크기로 만들어 자동증가가 발생하지 않도록, 증가단위를 크게지정) | * SQL Server는 Archive Redo로그에 대응되는 개념 없음\ |

4. 메모리구조

  • 시스템 공유 메모리 영역
ORACLESystem Global Area(SGA)
SQL ServerMemory Pool

\-여러 프로세스가 동시에 엑세스 할 수 있는 메모리영역
\-모든 DBMS는 공통적으로 사용하는 캐시영역이 있음(DB버퍼캐시,공유풀,로그버퍼)
\-그 외에 Lage Pool, JAVA pool 등을 포함하고, 시스템 구조와 제어구조를 캐싱하는 영역도 포함.
\-여러프로세스에 공유되기 때문에 Latch, 버퍼 Lock, 라이브러리캐시Lock/Pin 같은 액세스 직렬화 메커니즘이 사용

  • 프로세스 전용 메모리 영역
    \-오라클은 프로세스 기반의 아키텍처로 서버 프로세스가 자신만의 전용 메모리 영역을 가짐(PGA)
    \-데이터를 정렬하고 세션과 커서 정보를 저장역할
    \-쓰레드기반의 아키텍처를 사용하는 SQL Server는 프로세스 전용 메모리 영역을 갖지 않는다.

가. DB 버퍼 캐시 (DB Buffer Cache)

데이터파일로부터 읽어들인 데이터 블록을 담는 캐시영역
사용자 프로세스는 서버 프로세스를 통해 DB버퍼 캐시의 버퍼 블록을 동시에 엑세스(내부적으로 Buffer Lock을 통한 직렬화)
Direct Path Read 매커니즘이 작동하는 경우를 제외하면, 모든 블록 읽기는 버퍼 캐시를 통해 이루어짐
디스크에서 읽을때도 버퍼캐시에 적재한 후 읽음
데이터 변경도 버퍼캐시에 적재된 블록을 통해 이루어짐
변경된 블록(더티버퍼)은 주기적으로 DBWR 프로세스에 의해 데이터파일에 기록

1) 버퍼 블록의 상태


버퍼상태내용
Free 버퍼인스턴스 기동 후 아직 데이터가 읽혀지지 않아 비어 있는 상태거나, 데이터파일과 서로 동기화 되어 언제든지 덮어써도 되는 상태
Dirty Buffer버퍼가 캐시된 이후 변경이 발생했지만, 아직 디스크에 기록되지 않아 데이터 파일 블록과 동기화가 필요한 버퍼 블록,

이 버퍼 블록들이 재사용 되려면 디스크에 먼저 기록되어야 하며, 디스크에 기록되는 순간 Free 버포로 바뀜
Pinned 버퍼읽기 쓰기 작업이 현재 진행중인 버퍼블록
2) LRU 알고리즘 엑세스 반도가 낮은쪽 데이터 블록부터 밀어냄

나. 공유 풀 (Shared Pool)


ORACLEShared Pool
SQL Server프로시저 캐시

딕셔너리캐시와 라이브러리 캐시로 구성되며 버퍼캐시처럼 LRU 알고리즘을 사용
1) 딕셔너리 캐시
테이블, 인덱스와 같은 오브젝트는 물론 테이블스페이스, 데이터파일, 세그먼트, 익스텐트, 사용자, 제약사항과 같은 메타정보 저장
2) 라이브러리 캐시
SQL 실행에 관련된 모든 객체에 대한 정보 관리
서버 프로세스가 SQL을 작업할 때 사용되는 작업공간
SQL에 대한 분석정보 및 실행계획 저장
공유 SQL을 저장하기 위해 사용
라이브러리 캐시는 캐싱된 SQL과 그 실행계획의 재사용성을 높이는 것이 수행 성능을 높이고 DBMS 부하를 최소회하는 핵심 원리 임
바인드 변수 사용 및 기준에 맞는 SQL 작성으로 재사용성 높여줘야함

다. 로그 버퍼(Log Buffer)

SQL Server : 로그캐시
서버프로세스가 데이터 블록 버퍼에 변경을 가하기 전 Redo 로그 버퍼에 먼저 기록 \-> LGWR프로세스가 Redo 로그파일에 기록

라. PGA(Process Global Area)

  • 오라클의 서버 프로세스는 자신만의 PGA 메모리 영역을 할당 받아 이를 프로세스에 종속적인 고유 데이터를 저장하는 용도로 사용
  • PGA는 다른 프로세스와 공유되지 않은 독립적인 메모리 공간으로 똑같은 개수의 블록을 읽더라도 SGA버퍼 캐시에서 읽는 것 보다 훨씬 빠르다.
    1) UGA(User Global Area)
    • Shared Server 방식은 세션이 프로세스 개수보다 많아 질 수 있는 구조, 세션을 위한 독립적인 메모리공간이 필요
  • UGA는 전용서버 방식으로 연결할 때는 PGA에 할당, 공유서버 방식엔 SGA(Large pool 안)에 할당
    2) CGA(Call Global Area)
    • 오라클은 하나의 데이터베이스 Call을 넘어서 당므 Call까지 계속 참조되는 정보를 UGA에 담고, Call이 진행되는 동안에만 필요한 데이터는 CGA에 담는다.
    • CGA는 Parse Call, Execute Call, Excute, Fetch 단계별로 CGA가 추가로 할당 된다.
    • CGA에 할당된 공간은 Call이 끝나자 마자 해제되어 PGA로 반환된다.
      3)Sort Area
    • 데이터 정렬을 위해 사용되며, 부족할 때마다 chunk 단위로 조금씩 할당됨
    • 9i이전: 세션마다 sort_area_size 파라미터로 설정
    • 9i이후: workarea_size_policy 파라미터를 auto(defautl)로 설정하면 Oracle이 내부적으로 할당
    • sort 할당위치
      DML : CGA영역에 할당
      SELECT : 수행중간에 필요한 sort Area는 CGA, 최종 결과집합을 출력하기 직전 단계에서 필요한 sort area는 UGA에 할당
    • SQL Server는 PGA영영이 없으며, 정렬을 위해서는 Memory Pool안에 있는 버퍼캐시에서 수행하며
      세션관련 정보는 Memory Pool안의 Connection Context 영역에 저장

5. 대기 이벤트

  • DBMS 내부에서 활동하는 수많은 프로세스간에는 상호작용이 필요하며, 그 과정에서 다른 프로세스가 일을 마칠때까지 기다려야 하는 상황이 발생,
    그때마다 해당프로세스는 자신이 일을 계속 진행할 수 있는 조건이 충족될 때 까지 sleep 상태로 대기
ORACLE대기이벤트(Wait Event)
SQL Server대기유형(Wait Type)
  • Response Time = Service Time(Cpu Time) + Wait Time(Queue Time)
  • 서비스 시간(Services Time = Cpu Time) : 프로세스가 정상적으로 동작하며 일을 수행한 시간
  • 대기시간 (Wait Time = Queue Time) : 프로세스가 잠시 수행을 멈추고 대기한 시간|
  • Response Time Analysis 방법론 : Cpu Time과 Wait Time을 각각 brak down 하면서 서버의 일량과 대기시간을 분석
    Cpu Time : 파싱작업에 소비한 시간인지 쿼리 본연의 오퍼레이션 수행을 위해 소비한 시간인지 분석
    Wait Time : 각각 발생한 대기 이벤트를 분석해서 가장 시간을 많이 소비한 이벤트 중심으로 해결방안 모색

가. 라이브러리 캐시 부하


  • 라이브러리 캐시에서 SQL 커서를 찾고 최적화 하는 과정에서 경합이 발생하여 나타난 대기이벤트

    latch : shared pool

    latch : library cache
  • 라이브러리 캐시와 관련해서 자주 발생하는 대기이벤트로 수행중인 SQL이 참조하는 오브젝트에 다른 사용자가 DDL문장을 수행할때

    library cache lock

    library cache pin

나. 데이터베이스 Call 과 네트워크 부하

애플리케이션과 네트워크 구간에서 소모된 시간에 의해 나타난 이벤트
\-SQL*Net message from client : client로부터 다음 명령이 올때까지 idle 상태로 기다릴때 발생(데이터베이스 경합과 관계없음)
\-SQL*Net message to client : 메시지를 보냈는데 메시지를 받았다는 신호가 늦게 도착하는경우 이거나 , 클라언트가 너무 바쁠경우.
\-SQL*Net more data to client: 메시지를 보냈는데 메시지를 받았다는 신호가 늦게 도착하는경우 이거나 , 클라언트가 너무 바쁠경우.
\-SQL*Net more data from client : 클라이언트로부터 더 받을 데이터가 있는데 지연이 발생한 경우

다. 디스크 I/O 부하

디스크 I/O 발생할 때 나타나는 대기 이벤트
\-db file sequential read : Single Block I/O. 한번의 I/O call에 하나의 데이터 블록만 읽음. 인덱스 블록을 읽을때 발생
\-db file scattered read : Multi Block I/O . Table Full Scan 또는 Index Fast Full Scan 시 나타남
\-direct path read
\-direct path write
\-direct path write temp
\-direct path read temp
\-db file parallel read

라. 버퍼 캐시 경합

버퍼캐시에서 블록을 읽는 과정에서 경합이 발생하여 나타나는 대기 이벤트
\-latch : cache buffers chains
\-latch : cache buffers lru chain
\-buffers busy waits
\-free buffer waits

마. Lock 관련 대기 이벤트

  • Lock과 관련된 대기이벤트
    \-enq : TM - contention
    \-enq : TX - row lock contention
    \-enq : TX - index contention
    \-enq : TX - allocate ITL entry
    \-enq : TX contention
    \-latch free : 특정 자원에 대한 래치를 여러차례(2000번 가량) 요구했지만 해당 자원이 계속 사용중이어서 잠시 대기 상태로 빠질때마다 발생
  • Lock은 사용자 데이터를 보호하는 반면, Latch는 SGA에 공유되어 있는 갖가지 자료구조를 보호할 목적으로 사용하는 가벼운 LOCK
  • Latch도 일종의 Lock 이지만 큐잉(Queueing) 매커니즘을 사용하지 않음
  • 특정자원에 액세스하려는 프로세스는 래치 획득에 성공할때까지 반복해서 시도하나, 우선권은 부여받지 못함 (처음시도한 래치가 맨 나중에 래치획득에 성공할수도 있음)

그 외 대기이벤트
\-log file sync
\-checkpoint completed
\-log file switch completion
\-log buffer space