DB에 대한 공부를 더욱 진행 해야겠다는 생각으로
온라인에서 추천받은 'SQL 레벨업'이라는 책을 선택하게 되었다.
(절반 정도 읽었는데 새로운 내용이나 잘 정리된 내용들이 많아서 추천!)
DBMS의 전체적인 구조이다.
책에 있는 이미지와 가장 유사한 이미지라 가지고 와봤다.
(ORACLE의 구조이므로 다른 DBMS와는 다를 수 있다.)
개발자가 작성한 SQL이 가장 먼저 거치는 단계는 '쿼리평가 엔진'이다.
쿼리평가 엔진은 SQL 구문을 분석하여 어떤 '방식'으로 DB에 접근할지를 결정한다.
그리고 이때 결정되는 계획을 실행계획이라고 한다.
실행계획은 성능에 큰 영향을 미치므로 쿼리평가 엔진은 핵심 모듈이라고 할 수 있다.
버퍼 매니저는 연산과 데이터 캐시, 로그 버퍼에 활용하는 메모리 영역을 관리하며
디스크 용량 매니저는 Data를 '어디에' '어떻게' 저장할지를 관리한다.
트랜잭션 매니저와 락 매니저는 트랜잭션의 정합성을 유지하고
필요하다면 데이터에 락을 걸어 다른 사람의 요청을 대기시키는 역할을 한다.
리커버리 매니저는 데이터를 정기적으로 백업하고 문제가 생겼을 때 복구하는 기능을 수행한다.
SQL 성능을 높히려면 기억장치에 대한 이해가 필요하다.
성능&가격 - (레지스터,캐시(SRAM) > 메모리(DRAM) > 디스크(SSD, HDD))
간단히 말하면 비싼게 빠르다.
물론 전원이 나가도 데이터가 유지된다는 점에서 디스크의 장점은 있지만
상대적으로 속도에서는 비교가 되지 않을 정도로 느리다.(수십만~수백만배)
수십수백만배의 속도 차이가 있기 때문에 메모리를 최대한 활용하는 것은 중요하다.
일반적인 SQL 구문의 실행 시간 대부분은 디스크 입출력에 사용되기 때문이다.
이렇게 성능향상 목적으로 데이터 일부를 저장하는 메모리를 데이터 캐시라고 부르며
만약 실행 SELECT 구문의 데이터가 모두 이렇게 데이터 캐시에 있다면
디스크까지 갈 필요가 없어져 굉장히 빠르게 응답한다.
메모리를 활용하는 모듈 중 로그 버퍼는 갱신처리(INSERT, UPDATE, DELETE, MERGE)와
연관을 가지고 있다. DB의 갱신처리는 비동기 형식으로 이루어진다.
예를 들어 사용자가 갱신요청을 보냈을 때 이전 로직과 SQL에 문제가 없다면
일단 갱신이 완료되었다는 메시지를 리턴하고, 이후 실제 DB에 정보갱신을 진행하는 형식이다.
(동기 형식으로 진행하면 사용자가 실제 DB 갱신완료를 기다려야 하므로)
위에서 소개한 데이터 캐시(검색)와 로그 버퍼(갱신)의 비중은 시스템마다 다를 수는 있겠지만
보편적으로 데이터 캐시에 메모리 할당을 많이 하게된다.
그 이유는 DBMS는 기본적으로 검색을 메인으로 활용되는 경우가 많으며
갱신에 비해 검색에서 활용하는 레코드가 훨씬 많기 때문이다.
또 하나의 메모리 활용 모듈은 워킹 메모리로 정렬, 해시, 윈도우 함수, JOIN 등의
연산이 필요한 부분에서 활용된다. 워킹 메모리에서 주의해야 할 것은 필요한 만큼
메모리를 할당해주지 않으면 디스크를 끌어와서 사용하는 SWAP이 발생한다는 점이다.
이 경우 디스크에 접근하게 되기 때문에 메모리 사용에 비해 속도가 굉장히 느려질 수 있다.
이러한 SWAP은 DBMS의 안정성을 위한 것으로 조금 느리더라도 어떻게든 처리하여
메모리가 부족하면 다운되는 JAVA의 OOM과 같은 일을 막아준다.
(WINDOW 기반의 SQL Server의 경우는 OS와 같은 벤더에서 개발되어
밀접한 연계가 가능해 DBMS에 할당되는 메모리 자동조정이 가능하다고 한다.)
마지막으로 카탈로그 매니저에 대해 알아보며 DBMS의 구조에 관한 글을 마치고자 한다.
개발자에 의해 작성된 쿼리는 파서를 통해 parse(구문 분석)되어 기본적인 문법 확인을 받게되고
확인된 쿼리는 옵티마이저가 세운 실행계획에 따라 실행되는데
이 실행계획을 세울 때 필요한 통계정보를 제공하는 것이 바로 카탈로그 매니저이다.
카탈로그 매니저가 제공하는 통계정보는 다음과 같다.
- 각 테이블의 레코드 수
- 각 테이블의 필드 수와 필드의 크기
- 필드의 카디널리티(값의 개수)
- 필드 값의 히스토리그램(값의 분포 상태)
이러한 통계정보가 정확하지 않으면 아무리 성능 좋은 옵티마이저라도
좋은 실행계획을 도출 할 수 없고 결국 최적의 SQL 성능을 낼 수 없게된다.
이러한 통계정보는 테이블의 데이터가 많이 바뀌거나 자주 쓰는 중요한 테이블의 경우
위의 명령어등을 통해 수동으로 갱신하거나, DBMS에 따라 자동으로 갱신되기도 한다.
통계정보 갱신작업은 DATA의 크기와 수에 따라 몇십분에서 몇시간이 소요 될 수 있으므로
서버 이용이 뜸한 시간(야간)을 활용하여 서비스에 지장이 없도록 하는 것이 좋을 것 같다.