과목Ⅲ SQL 고급 활용 및 튜닝
제1장 SQL 수행 구조
제1절 데이터 베이스 아키텍처
Oracle과 SQL Server 모두 물리적으로는 데이터 파일에 데이터를 저장하고 관리한다. 공간을 할당하고 관리하는 논리적인 구조도 크게 다르지 않지만 약간의 차이는 있다.
임시 데이터 파일은 대량의 정렬이나 해시 작업을 위해 사용된다.
로그 파일은 DB 버퍼 캐시에 가해지는 모든 변경사항을 기록했다가 캐시 복구나 데이터베이스 복구에 사용된다.
메모리는 시스템 공유 메모리 영역과 프로세스 전용 메모리 영역으로 나뉜다.
시스템 공유 메모리는 여러 프로세스에 공유되기 때문에 내부적으로 래치(Latch), 버퍼 Lock, 라이브러리 캐시 Lock/Pin풀, 로그 버퍼 등이 있다.
프로세스 전용 메모리는 개별 서버 프로세스만의 전용 데이터를 저장해 두는 메모리 영역을 말한다. 가장 큰 용도는 데이터 정렬에 있고, 세션과 커서에 관한 상태 정보를 저장하는 용도로도 사용된다. 다른 프로세스와 공유되지 않기 때문에 래치와 같은 직렬화 메커니즘이 필요 없어 버퍼 캐시에서 블록을 읽을 때보다 훨씬 빠르다.
서버 프로세스는 사용자 프로세스와 통신하면서 사용자의 각종 명령을 처리하며, 백그라운드 프로세스는 Dirty 버퍼와 로그 버퍼를 디스크에 기록하고 인스턴스 및 프로세스를 복구하는 등 각 프로세스별로 주어진 역할을 수행한다.
수 많은 프로세스 간 상호작용 과정에서 다른 프로세스를 기다려야 하는 상황이 자주 발생한다. 그때마다 DBMS는 대기 이벤트를 남겨 해당 프로세스가 현재 어떤 상태에 놓였는지 분석할 수 있게 해 준다.
제2절 SQL 처리 과정
SQL은 기본적으로 구조적(structured) 이고 집합적(set-based) 이고 선언적(declarative)인 질의 언어다.
SQL은 파싱, 최적화, 로우소스 생성 과정을 거쳐 실행된다.
SQL 옵티마이저는 사용자가 원하는 작업을 가장 효율적으로 수행할 수 있는 최적의 데이터 액세스 경로를 선택해주는 DBMS의 핵심 엔진이다.
실행계획은 SQL 옵티마이저가 생성한 처리절차를 사용자가 확인할 수 있게 트리 구조로 표현한 것이다.
통계정보가 정확하지 않거나 기타 다른 이유로 옵티마이저가 잘못된 판단을 할 때 개발자가 옵티마이저 힌트를 이용해 더 좋은 실행계획으로 유도할 수 있다.
제3절 데이터베이스 I/O 메커니즘
Oracle을 포함한 모든 DBMS에서 I/O는 블록(=페이지) 단위로 이루어진다.
물리적으로 한정된 시스템 자원을 효율적으로 사용하기 위해 디스크 I/O를 최소화하고 버퍼 캐시 효율을 높이는 것이 I/O 튜닝의 목표다.
네트워크 문제이든, 파일시스템 문제이든 I/O 성능에 관한 가장 확실하고 근본적인 해결책은 논리적인 블록 요청 횟수를 최소화하는 것이다.
시퀀셜 액세스는 레코드간 논리적 또는 물리적인 순서를 따라 차례대로 읽어 나가는 방식이다. 반면 랜덤 액세스는 레코드 간 논리적ㆍ물리적 순서를 따르지 않고 한 건을 읽기 위해 한 블록씩 접근하는 방식이다.
Single Block I/O는 한 번의 I/O Call에 하나의 데이터 블록만 읽어 메모리에 적재하는 방식이고, MultiBlock I/O는 I/O Call 발생 시점에 인접한 블록들을 같이 읽어 메모리에 적재하는 방식이다. 인덱스를 이용해 소량의 데이터를 읽을 때는 Single Block I/O 방식이 효율적이고, 대량의 데이터를 Full Scan할 때는 MultiBlock I/O 방식이 효율적이다.
논리적인 I/O 요청 횟수를 최소화하는 것이 I/O 효율화 튜닝의 핵심 원리다. 그러기 위해서는 필요한 최소 블록만 읽도록 SQL을 작성하는 것이 무엇보다 중요하다. 옵티마이저의 성능을 최대한 끌어올리기 위해서는 그만한 옵티마이징 팩터를 제공해야 하며, 옵티마이저 힌트를 이용해 사용자가 직접 최적의 액세스 경로로 유도해야 할 때도 있다.
제2장 SQL 분석 도구
제1절 예상 실행계획
Oracle은 Explain plan 명령으로 실행계획을 수집한다.
Oracle은 AutoTrace 명령어로 예상 실행계획뿐 아니라 여러 가지 실행통계도 확인할 수 있다.
DBMS_XPLAN 패키지를 이용해 수집된 실행계획을 출력한다.
SQL Server는 set showplan_text on 명령으로 예상 실행계획을 확인할 수 있다.
SQL Server는 set showplan_all on 명령문을 통해 PhysicalOp(물리 연산자), LogicalOp(논리 연산자), EstimateRows(예상 로우 수) 등을 확인할 수 있다.
제2절 SQL 트레이스
Oracle은 sql_trace 파라미터를 활성화함으로써 SQL 트레이스를 수집할 수 있다.
Oracle은 수집된 트레이스 정보를 tkprof 명령어를 통해 리포트를 출력한다.
Oracle에서 gather_plan_statistics 힌트를 이용하면 트레이스 정보를 SGA 메모리에 수집할 수 있고, 그 정보를 DBMS_XPLAN 패키지로 포맷팅할 수 있다.
SQL Server는 statistics profile, statistics io, statistics time 옵션들을 활성화(on) 함으로써 SQL 트레이스 정보를 확인할 수 있다.
제3절 응답 시간 분석
DBMS 내부에서 활동하는 수많은 프로세스 간에는 상호작용이 필요하며, 그 과정에서 다른 프로세스가 일을 마칠 때까지 기다려야만 하는 상황이 자주 발생한다.
DBMS는 프로세스가 OS에 CPU를 반환하고 대기할 때마다 로그를 남긴다. 오라클은 이를 ‘대기 이벤트(Wait Event)’ 라고 부르고, SQL Server에서는 ‘대기 유형(Wait Type)’ 이라고 부른다.
응답시간(Response Time)을 Service Time과 Wait Time의 합으로 정의하고, 대기(Wait) 원인을 분석함으로써 병목을 해소해 나가는 성능 관리 방법론을 ‘응답 시간 분석(Response Time Analysis)’ 이라고 한다.
응답 시간 분석 방법론을 지원하는 많은 성능 관리 도구가 개발댔고, AWR은 이를 지원하는 Oracle 표준 도구다.
제3장 인덱스 튜닝
제1절 인덱스 기본 원리
인덱스의 가장 기본적인 구조는 B*Tree 인덱스다.
B*Tree 인덱스 탐색 과정은 수직적 탐색과 수평적 탐색으로 나눌 수 있다.
Oracle이 사용하는 인덱스 스캔 방식에는, Index Range Scan, Index Unique Scan, Index Full Scan, Index Fast Full Scan, Index Skip Scan 등이 있다. SQL Server가 사용하는 인덱스 스캔 방식에는 Index Seek와 Index Scan이 있다.
Oracle에서 제공하는 인덱스로는 B*Tree 인덱스, 비트맵(Bitmap) 인덱스, 함수기반 인덱스, 리버스 키(Reverse Key) 인덱스, 클러스터 인덱스 등이 있다. SQL Server의 인덱스 종류로는 클러스터형(Clustered) 인덱스와 비클러스터형(NonClustered) 인덱스가 있다.
인덱스 선두 컬럼을 조건절에서 가공하면 인덱스가 정상적으로 사용될 수 없다.
특히 DBMS 내부적으로 일어나는 묵시적(Implicit) 형 변환 때문에 인덱스가 사용되지 못하는 경우가 있는지 주의를 기울여야 한다.
제2절 테이블 액세스 최소화
인덱스 튜닝 원리는 테이블 랜덤 액세스 최소화와 인덱스 스캔범위 최소화라는 2가지로 요약될 수 있다.
특히 인덱스를 경유한 테이블 랜덤 액세스가 성능을 저하시키는 주요인이고, 그 발생량이 일정 수준을 넘으면 테이블 전체를 스캔하는 것보다 오히려 늦다.
인덱스 컬럼 기준으로 테이블 데이터가 모여 있는 정도를 의미하는 클러스터링 팩터에 따라 인덱스 손익 분기점이 많이 달라진다.
테이블 액세스 최소화를 위한 가장 일반적인 방법은 인덱스에 컬럼을 추가하는 것이다.
IOT, 클러스터형 인덱스, 클러스터 테이블 등을 적용함으로써 테이블 액세스를 최소화할 수 있다.
제3절 인덱스 스캔 효율화
인덱스 스캔 범위를 최소화하는 것도 인덱스 튜닝의 중요한 요소다. 인덱스 선두 컬럼이 Between, 부등호, Like 같은 범위검색 조건일 때가 문제다.
인덱스 스캔 범위를 최소화하기 위해 인덱스 선두 컬럼을 ‘=’ 이나 In-List 조건으로 바꿔주는 것이 효과적일 수 있고, Index Skip Scan을 활용하는 것도 효과적이다.
제4절 인덱스 설계
인덱스를 설계할 때는 조건절에 항상 (또는 자주) 사용되는 컬럼을 선정하고, 그 중에서 ‘=’ 조건으로 자주 조회되는 컬럼을 앞쪽에 두어야 한다.
인덱스는 단순한 공식보다는 쿼리 수행 빈도, 업무상 중요도, DML 발생량 등을 종합적으로 고려해서 설계해야 한다.
제4장 조인 튜닝
제1절 NL 조인
NL 조인은 인덱스를 이용한 댄럼 액세스 위주이고, 한 레코드씩 순차적으로 진행하므로 소량의 데이터를 조인할 때 효과적이다. 특히 부분범위처리가 가능한 OLTP 환경에서 유용하다.
제2절 소트 머지 조인
소트 머지 조인은 양쪽 집합을 먼저 정렬한 다음, ㅇ림시 영역에 정렬된 양쪽 집합을 모두 스캔하면서 조인을 수행한다.
제3절 해시 조인
해시조인은 조인되는 두 집합을 각각 Build Input과 Probe Input 으로 지정하고, 우선 Build Input 각 레코드에 해시 함수를 적용해 해시 맵(Hash Map)을 만든다. 그러고 나서 남은 Probe Input을 하나씩 읽으면서 해시 맵을 탐색함으로써 조인을 수행한다.
제4절 스칼라 서브 쿼리
스칼라 서브 쿼리의 캐싱 효과를 이용해 큰 성능 개선 효과를 얻는 경우가 종종 있다.
제5절 고급 조인 기법
인라인 뷰를 활용해 단계적으로 조인을 수행하는 방법이 유용할 때가 있다.
배타적 관계의 조인, 부등호 조인 등을 활용하면 복잡한 업무를 쉽게 처리할 수 있다.
Between 연산자를 이용하면 선분이력 모델을 쉽게 제어할 수 있다.
인덱스와 조인 수행 원리를 정확히 이해한다면, 본서에서 소개한 것 외에도 다양한 고급 조인 기법을 개발해 낼 수 있다.
제5장 SQL 옵티마이저
제1절 SQL 옵티마이징 원리
옵티마이저(Optimizer)는 SQL을 가장 빠르고 효율적으로 수행할 최적(최저비용)의 처리경로를 생성해 주는 DBMS 내부의 핵심엔진으로서, 옵티마이저에 의해 생성한 SQL 처리절차를 ‘실행계획(Execution Plan)’이라고 부른다.
규칙기반 옵티마이저(Rule-Based Optimizer)는 미리 정해 놓은 규칙에 따라 액세스 경로를 평가하고 실행계획을 선택한다.
비용기반 옵티마이저(Cost-Based Optimizer)는 비용을 기반으로 최적화를 수행한다. 여기서 ‘비용(Cost)’은 쿼리를 수행하는데 소요되는 일량 또는 시간을 뜻하며, 어디까지나 예상치다.
옵티마이저는 사람이 만든 소프트웨어 엔진에 불과하며 결코 완벽할 수 없다. 이런 부족한 부분을 사용자가 메워주려면 옵티마이저 원리를 정확히 이해해야 한다.
실행계획을 수립할 때 CBO는 SQL 문장에서 액세스할 데이터 특성을 고려하기 위해 통계정보를 이용한다. 따라서 통계정보가 항상 데이터 상태를 정확하게 반영하도록 관리해 주어야 한다.
선택도(Selectivity)는 전체 대상 레코드 중에서 특정 조건에 의해 선택될 것으로 예상되는 레코드 비율을 말한다. 카디널리티(Cardinality)는 특정 액세스 단계를 거치고 나서 출력될 것으로 예사되는 결과 건술르 말하며, 총 로우수에 선택도를 곱해서 구한다.
컬럼 히스토그램 정보를 이용하면 더 정확하게 카디널리티를 구할 수 있으며, 특히 분포가 균일하지 않은 컬럼 조건을 분석할 때 유용하다.
제2절 SQL 공유 및 재사용 (파싱 부하)
무거운 파싱 과정을 거친 SQL과 실행계획은 여러 사용자가 공유하면서 재사용할 수 있도록 공유 메모리에 캐싱해둔다.
공유 메모리에서 SQL과 실행계획을 찾아 곧바로 실행하는 것을 ‘소프트파싱’이라고 한다.
공유 메모리에서 SQL을 찾지 못해 실행계획을 새로 생성하고 실행하는 것을 ‘하드파싱’이라고 한다.
공유 메모리에서 SQL을 찾기 위해 사용되는 키 값을 SQL 문장 그 자체다. 따라서 중간에 작은 글자 하나만 달라도 DBMS는 서로 다른 SQL로 인식해 실행계획을 새로 생성한다.
조건절이 동적으로 생성되는 리터럴(Literal) SQL로 프로그램을 작성하면 새로운 값이 입력될 때마다 하드파싱을 일으켜 쿼리 성능이 저하됨은 물론 시스템 부하를 가중시킨다.
OLTP 환경에서 SQL 파싱 부하를 최소화하려면 반드시 바인드 변수를 사용해야 한다.
바인드 변수를 사용하면 옵티마이저가 컬럼 히스토그램을 활용하지 못하는 단점이 있으므로 값의 분포가 균일하지 않은 컬럼을 조건절에 사용할 때는 UNION ALL을 이용해 실행계획을 분기하는 방안을 고려해야 한다.
같은 SQL을 반복 수행하고자 할 때, 애플리케이션 커서 캐싱 기법을 이용하면 캐시에서 SQL 실행계획을 찾는 부하를 없애줘 성능 향상에 도움이 된다.
제3절 쿼리 변환
쿼리 변환(Query Transformation)은, 옵티마이저가 SQL을 분석해 의미적으로 동일하면서도 더 나은 성능이 기대되는 형태로 재작성하는 것을 말한다.
중첩된 서브쿼리를 풀어내는 쿼리 변환을 ‘서브쿼리 Unnesting’이라고 한다. 서브쿼리를 메인쿼리와 같은 레벨로 푸렁낸다면 다양한 액세스 경로와 조인 메소드를 평가할 수 있다.
뷰 쿼리 블록을 액세스 쿼리 블록과의 머지(Merge)하는 쿼리 변환을 ‘뷰 Merging’ 이라고 한다.
뷰를 참조하는 쿼리 블록의 조건절을 뷰 쿼리 블록 안으로 밀어 넣는 쿼리 변환을 ‘조건절 Pushing’ 이라고 한다.
‘(A=B)이고 (B=C)이면 (A=C)이다’는 추론을 통해 새로운 조건절을 내부적으로 생성해 주는 쿼리 변환을 ‘조건절 이행’이라고 한다.
그 외에도 불필요한 조인을 제거하고, OR 조건을 Union 으로 변환하고, 집합 연산을 조인으로 변환하는 등 내부적으로 다양한 쿼리 변환이 일어난다.
제6장 고급 SQL 튜닝
제1절 소트 튜닝
메모리 상의 소트 영역 내에서 데이터 정렬 작업을 완료하는 것이 최적이지만, 대량의 데이터를 정렬할 땐 디스크 소트가 불가피하다. 특히 전체 대상 집합을 디스크에 기록했다가 다시 읽는 작업을 여러 번 반복하는 경우 SQL 수행 성능은 극도로 나빠진다.
불필요하게 자주 소트를 유발하진 않는지 데이터 모델 측면에서의 검토가 필요하다.
가급적 소트가 발생하지 않도록 SQL을 작성해야 한다.
정렬 기준으로 구성된 인덱스를 활용하면 소트 연산을 대체할 수 있다.
소트가 불가피하다면 소트 영역을 적게 사용하도록 SQL을 작성해야 한다.
소트 영역 크기를 조정하는 튜닝 방안도 고려해야 할 때가 있다.
제2절 DML 튜닝
테이블 데이터를 바꾸면 관련된 인덱스에도 변경이 발생하므로 인덱스 개수가 많을 수록 DML 성능은 나빠진다.
Direct Path Insert 또는 로깅 최소화 옵션을 사용하면 대량의 데이터를 입력할 때 성능을 크게 높일 수 있다.
각 DBMS가 제공하는 확장 Update 문을 활용하면 Update 성능을 높이는데 크게 도움이 된다.
대량의 데이터를 Update 할 땐, Truncate & Insert 방식이 효과적이다.
제3절 데이터베이스 Call 최소화
데이터베이스 Call과 결과 집합 전송은 네트워크를 통해 이루어지며, 서버와의 Roundtrip 횟수가 많을수록 쿼리 수행속도가 떨어지는 것은 당연하다. 따라서 데이터베이스 Call 종류와 특성을 잘 이해함으로써 그 횟수를 줄이려고 노력해야 한다.
루프를 돌면서 여러 작업을 반복 수행하는 프로그램을 One SQL로 구현하면 큰 성능 개선 효과를 얻을 수 있으며, 그 핵심원리는 데이터베이스 Call을 줄이는 데에 있다.
Array Processing을 잘 활용하면 데이터베이스 Call 횟수를 크게 줄여줘 One SQL로 통합할 때와 비슷한 수준의 성능 개선 효과가 있다.
쿼리 결과 집합을 전송할 때, 전체 데이터를 연속적으로 전송하지 않고 사용자로부터 Fetch Call이 있을 때마다 일정량씩 나누어서 전송하는 것을 이른바 부분범위처리라고 한다.
부분범위처리 원리를 이용하면 대용량 OLTP 환경에서 극적인 성능 개선 효과를 얻을 수 있다.
대량 데이터를 읽을 때는 ArraySize를 가급적 크게 설정하는 것이 유리하다. 반대로 일부 데이터만 읽다가 멈출 때는 ArraySize를 작게 설정하는 것이 유리하다.
원격 조인 시 네트워크를 통한 데이터 전송량을 줄임으로써 성능을 높일 수 있다.
메인 쿼리가 참조하는 사용자 정의 함수에 또 다른 쿼리문이 내장돼 있으면 수행 성능이 훨씬 나빠지는데, 이는 함수에 내장된 쿼리를 수행될 때마다 Recursive Call이 반복적으로 일어나기 때문이다.
사용자 정의 함수는 소량의 데이터를 조회할 때, 또는 부분범위처리가 가능한 상황에서 제한적으로 사용해야 한다. 성능을 위해서라면 가급적 조인 또는 스칼라 서브 쿼리 형태로 변환하려고 노력해야 한다.
제4절 파티션닝
파티션 기능은 관리적 측면과 성능적 측면에서 매우 유용하다.
Range, Hash, List, Composite 등 파티션 유형별 특징을 이해하는 것이 무엇보다 중요하다.
성능적인 측면의 파티션 유용성은 무엇보다도 파티션 Pruning 기능에서 나온다.
인덱스 파티션을 테이블 파티션과 구분할 줄 알아야 한다. 그리고 파티션 인덱스에 다양한 구성이 존재한다는 사실을 이해하고, 상황에 맞는 전략을 채택해야 한다.
제5절 대용량 배치 프로그램 튜닝
배치(Batch) 프로그램은, 사용자와의 상호작용 없이 대량의 데이터를 처리하는 일련의 작업들을 묶어 정기적으로 반복 수행하거나 정해진 규칙에 따라 자동으로 수행한다.
배치 프로그램의 수행 주기가 점점 단축되고 있다.
온라인 트랜잭션을 처리하는 프로그램과 달리 배치 프로그램은 항상 전체 처리 속도 향상을 최적화 목표로 해야 한다.
한정된 자원을 경합 없이 최적으로 사용하도록 타임 윈도우를 조정하는 작업이 필요하다.
대용량 배치 프로그램 성능을 높이는 데는 효과적인 One SQL 구현 능력이 매우 중요시된다.
Array Processing, 파티션 기능, 병렬 처리 등을 잘 활용하면 큰 효과를 볼 수 있다.
병렬 처리란, SQL 문이 수행해야 할 작업 범위를 여러 개의 작은 단위로 나누어 여러 프로세스(또는 쓰레드)가 동시에 처리하는 것을 말한다. 여러 프로세스가 동시에 작업하므로 당연히 대용량 데이터 처리 속도를 높여준다.
병렬 처리 성능을 개선하는 데는 프로세스 간 상호작용(Inter Operation Parallelism)을 줄여주는 것이 도움이 된다.
pq_distribute 힌트를 잘 활용하면 프로세스 간 통신 양을 줄이는데 도움이 된다.
제6절 고급 SQL 활용
DECODE 함수나 CASE 문을 활용하면 IF ELSE 같은 분기 조건을 포함하는 복잡한 처리절차를 One SQL로 구현하는데 도움이 된다.
카티션 곱을 이용해 데이터를 복제하는 것도 One SQL을 구현하는 필수 기법 중 하나다.
Union All을 이용하면 M:M 관계의 조인을 해결하거나 Full Outer Join을 대체할 수 있다.
데이터베이스 Call과 네트워크 부하를 줄이기 위해 화면 페이징 처리가 필요하지만, I/O 효율까지 고려한 효과적인 페이징 처리에 대한 연구가 뒤따라야 한다.
윈도우 함수나 With 구문 같은 신기능을 활용하면 복잡한 업무 요건을 손쉽게 처리함과 동시에 성능까지 높일 수 있다.
제7장 Lock과 트랜잭션 동시성 제어
제1절 Lock
공유 Lock끼리는 호환되므로 한 자원에 여러 사용자가 동시에 공유 Lock을 설정할 수 있다.
배타적 Lock은 어떤 Lock 모드와도 호환되지 않아 오직 한 사용자만이 Lock을 설정할 수 있다.
Oracle은 데이터를 읽을 때 공유 Lock을 사용하지 않는다. 따라서 읽기 작업이 갱신 작업을 방해하거나 기다리지 않는다.
Oracle이 공유 Lock을 사용하지 않고도 일관성을 유지할 수 있는 것은 Undo 데이터를 이용한 다중버전 동시성제어 메커니즘을 사용하기 때문이다.
블로킹(Blocking)과 교착상태(Deadlock)는 다르다. 블로킹은, Lock 경합이 발생해 특정 세션이 작업을 진행하지 못하고 멈춰 선 상태를 말한다. 교착상태(Deadlock)는, 두 세션이 각각 Lock을 설정한 리소스를, 서로 액세스하려고 마주 보고 진행하는 상황을 말한다. 둘 중 하나가 뒤로 물러나지 않으면 영영 풀릴 수 없다.
제2절 트랜잭션
트랜잭션(Transaction)은 업무 처리를 위한 논리적인 작업 단위다.
트랜잭션의 주요 특징은 원자성, 일관성, 격리성, 영속성으로 요약된다.
낮은 단계의 격리성 수준에서 발생할 수 있는 현상으로는, Dirty Read, Non-Repeatable Read, Phantom Read가 있다.
ANSI/ISO SQL 표준에서 정의한 트랜잭션 격리성 수준으로는 Read Uncommitted, Read Committed, Repeatable Read, Serializable Read 4가지가 있다.
제3절 동시성 제어
다수 사용자에 의한 다중 트랜잭션이 동시에 작동할 때 DBMS는 이들 트랜잭션의 상호 간섭 작용에서 데이터베이스를 보호할 수 있어야 하며, 이를 동시성 제어라고 한다.
다수 사용자가 데이터를 동시에 액세스할 때 Lock을 통해 직렬화 한다.
동시성 제어가 어려운 이유는 동시성과 일관성은 트레이드 오프 관계이기 때문이다.
동시에 실행되는 트랜잭션 수를 최대화하면서도 입력, 수정, 삭제 검색 시 데이터 무결성이 유지되도록 노력해야 한다.
동시성 제어 기법에는 비관적 동시성 제어와 낙관적 동시성 제어가 있다.
Oracle 을 시작으로 많은 DBMS가 다중버전 동시성 제어(MVCC) 메커니즘을 도입하고 있다.
MVCC 메커니즘 하에서는 읽기 작업과 쓰기 작업이 서로 방해하지 않아 동시성을 높이면서도 높은 읽기 일관성을 유지해 준다.
문장수준 읽기 일관성은, 다른 트랜잭션에 의해 데이터의 추가ㆍ변경ㆍ삭제가 발생하더라도 단일 SQL 문 내에서 일관성 있게 값을 읽는 것을 말한다. 일관성 기준 시점은 쿼리 시작 시점이 된다.
트랜잭션 수준 읽기 일관성은, 다른 트랜잭션에 의해 데이터의 추가ㆍ변경ㆍ삭제가 발생하더라도 트랜잭션 내에서 일관성있게 값을 읽는 것을 말한다. 일관성 기준 시점은 트랜잭션 시작 시점이 된다.
'공부는 평생하는 것이다 > SQLP(D)' 카테고리의 다른 글
[SQLD/SQLP] [노트정리] 제1장 데이터 모델링의 이해(2) (2) | 2022.10.15 |
---|---|
[SQLD/SQLP] [노트정리] 제1장 데이터 모델링의 이해(1) (0) | 2022.10.14 |
[SQLD/SQLP] SQL 전문가 가이드 2020개정판 요약정리(과목Ⅱ) (0) | 2022.10.12 |
[SQLD/SQLP] SQL 전문가 가이드 2020개정판 요약정리 (과목Ⅰ) (0) | 2022.10.11 |
SQLP(SQLD) 추천 서적 (공부할 때 필요한 책) (0) | 2022.10.10 |