DBMS 아키텍쳐
DBMS 아키텍쳐 개요
- 쿼리 평가 엔진
- 사용자가 입력한 SQL 구문을 분석하고 실행 계획을 결정
- 실행 계획(Explain Plan): 어떤 순서로 기억장치에 데이터를 접근할지 결정하는 계획
- 쿼리(query): SELECT 구문 또는 SQL 구문 전체를 의미
- 버퍼 매니저
- 특별한 용도로 사용되는 버퍼 영역을 관리
- 디스크 용량 매니저와 연동
- 디스크 용량 매니저
- 데이터 I/O 제어
- 트랜잭션 매니저와 락 매니저
- 트랜잭션의 정합성을 유지
- 필요할 경우 데이터에 락을 걸어 요청을 대기시킴
- 리커버리 매니저
- DBMS에 장애가 발생했을 때에 대비하여 데이터를 정기적으로 백업하고 문제가 일어났을 때 복구
DBMS와 버퍼
기억장치의 계층 (memory hierarchy)
- 기억장치는 기억 비용, 데이터를 저장하는 데에 드는 비용에 따라 구분
- 아래로 내려갈수록 기억 비용은 적어지지만 데이터 접근 속도는 떨어짐
DBMS와 기억장치의 관계
- 하드디스크(HDD)
- DBMS가 주로 데이터를 저장하는 매체, 범용성이 높음
- 메모리
- SQL 구문의 실행 속도를 높이기 위해 자주 접근하는 데이터를 메모리에 적재 → buffer 또는 cache
- 버퍼에 데이터를 어떻게, 어느 정도의 기간 동안 올릴 지를 관리하는 것이 버퍼 매니저
메모리 위에 있는 두 개의 버퍼
- 데이터 캐시
- 디스크에 있는 데이터의 일부를 메모리에 유지
- 로그 버퍼
- DBMS는 갱신과 관련된 SQL 구문을 사용자로부터 받으면 곧바로 저장소에 있는 데이터를 변경하지 않고 로그 버퍼에 변경 정보를 기록
- 저장소 변경이 끝날 때까지 사용자가 기다리지 않게 하고 내부적으로 데이터를 처리 (비동기)
메모리의 성질이 초래하는 트레이드오프
- 일반적으로 사용하는 메모리는 전원 공급이 없을 경우 데이터가 사라짐
- 장애가 발생했을 때 로그 버퍼 위에 존재하는 데이터가 저장소에 반영되기 전에 사라지면 데이터의 정합성이 깨짐
- 이를 회피하고자 DBMS는 커밋 시점에 반드시 갱신 정보를 영속적인 저장소에 존재하는 로그 파일에 작성
- 커밋 때는 반드시 디스크에 동기 접근이 일어나므로 지연 발생 가능
시스템 특성에 따른 트레이드오프
- 물리 메모리에 여유가 있다면 데이터 캐시를 되도록 많이 할당할 것을 추천
- 갱신 처리에 많은 자원이 필요할 경우 로그 버퍼를, 검색 처리에 많은 자원이 필요할 경우 데이터 캐시를 크게 잡음
추가적인 영역 ‘워킹 메모리’
- 정렬 또는 해시 관련 처리에 사용되는 작업용 영역
- 정렬: ORDER BY 구, 집합 연산, 윈도우 함수
- 해시: 테이블 등의 결합에서 해시 결합
- DBMS마다 명칭 다름
- Oracle: PGA(Program Global Area)
- PostgreSQL: 워크 버퍼
- MySQL: 정렬 버퍼
- 이 영역이 다루려는 데이터양보다 작을 경우 대부분의 DBMS에서 저장소를 사용
- DBMS는 메모리가 부족하다는 이유로 처리를 중단하지 않음
DBMS와 실행 계획
DBMS의 쿼리 처리 흐름
- 파서(parser)
- SQL 구문이 문법에 맞는지 검사하고 구문을 정형적인 형식으로 변환
- 옵티마이저(optimizer)
- 인덱스 유무, 데이터 분산 또는 편향 정도, DBMS 내부 매개변수 등의 조건을 고려하여 선택 가능한 많은 실행 계획을 작성
- 실행 계획의 비용을 연산하고 가장 비용이 낮은 실행 계획을 선택
- 카탈로그 매니저(catalog manager)
- 카탈로그: DBMS의 내부 정보를 모아놓은 테이블로 테이블 또는 인덱스의 통계 정보가 저장됨
- 카탈로그 매니저는 옵티마이저가 실행 계획을 세울 때 옵티마이저에 카탈로그 정보를 제공
- 플랜 평가(plan evaluation)
- 옵티마이저가 세운 실행 계획 중 최적의 실행 결과를 선택
실행 계획을 선택한 이후 DBMS는 실행 계획을 절차적인 코드로 변환하고 데이터에 접근
옵티마이저와 통계 정보
카탈로그에 포함되어 있는 통계 정보
- 각 테이블의 레코드 수
- 각 테이블의 필드 수와 필드의 크기
- 필드의 cardinality(값의 개수)
- 필드값의 히스토그램
- 필드 내부에 있는 NULL 수
인덱스 정보
- 테이블에서 CRUD가 수행될 때 카탈로그 정보가 갱신되지 않으면 옵티마이저는 오래된 정보를 바탕으로 실행 계획을 수립 → 통계 정보 갱신 필요
- 그러나 통계 정보 갱신은 실행 비용이 굉장히 높은 작업이므로 갱신 시점을 확실하게 검토해야 함
실행 계획이 SQL 구문의 성능을 결정
실행 계획 확인 방법
|DBMS 이름|명령어| |—|—| |Oracle|set autotrace traceonly| |Microsoft SQL Server|SET SHOWPLAN_TEXT ON| |DB2|EXPLAIN ALL WITH SNAPSHOT FOR SQL 구문| |PostgreSQL|EXPLAIN SQL 구문| |MySQL|EXPLAIN EXTENDED SQL 구문|
테이블 풀 스캔의 실행 계획
- 조작 대상 객체
- 테이블 이외에도 인덱스, 파티션, 시퀸스처럼 SQL 구문으로 조작할 수 있는 객체
- 객체에 대한 조작의 종류
- 순차적인 접근, 테이블 풀 스캔
- 조작 대상이 되는 레코드 수
- 모든 레코드를 삭제 후 실행 계획을 다시 검색해도 실행 계획이 변하지 않음
- 옵티마이저는 테이블을 보는 것이 아니라 통계라는 메타 정보를 봄
인덱스 스캔의 실행 계획
- 조직 대상 객체
- 레코드 1개
- 접근 대상 객체와 조작
- 인덱스 스캔은 모집합 레코드 수에서 선택되는 레코드 수가 많을수록 테이블 풀 스캔보다 빠름
- 시퀸셜 스캔 O(n) vs. 인덱스 스캔 O(logn)
간단한 테이블 결합의 실행 계획
- 결합 알고리즘
- Nested Loops: 한쪽 테이블을 읽으면서 레코드 하나마다 결합 조건에 맞는 레코드를 다른쪽 테이블에서 찾음
- Sort Merge: 결합 키로 레코드를 정렬하고 순차적으로 두 개의 테이블을 결합
- Hash: 결합 키값을 해시 값으로 매핑
실행 계획의 중요성
- 최근의 옵티마이저는 꽤 우수하지만 완벽하지는 않음
- 실행 계획을 수정하기 위해서는 SQL 구문들이 어떠한 접근 경로(access path)로 데이터를 검색하는지 알아야 함
- 이는 물리 계층을 은폐한다는 RDBMS의 목표를 거스르는 일이지만 필요한 경우도 있음