DB/Oracle

오라클 SQL 처리과정 (이해잘됨)

OIMKHOT 2022. 6. 9. 14:55

 

사용자가 SQL*Plus에 접속하면서 유저프로세스가 생성되었다.

 

오라클의 Listener 를 통해 DB에 접속하고 명령어를 실행하면 서버프로세스가 할당되면서 오라클 내부에서 해당 작업을 처리하게 된다.

 

크게 Parse, Execute, Fetch로 나눌 수 있고 Fetch 단계는 사용자에게 명령어를 반환하는 작업이므로 SELECT문을 수행할 때만 적용되는 단계이다.

 

서버 프로세스에 의해 가장 먼저 수행되는 것은 Parse 작업이다.

 

1. Parse

Parser라는 서브엔진에 의해 다음과 같은 검사를 수행한다.

 

1) Syntax Check : 먼저 문법적 오류가 없는지 확인한다. 오류가 있다면 에러를 반환하고 마무리한다.

 

2) Semantic Check : 필요로 하는 오브젝트가 실제로 존재하는지, 접근 권한이 충분한지, 제대로 된 컬럼명을 사용했는지 등을 확인한다.

 

3) 실행계획(Shared Pool Caching) Check : 오라클은 SQL 실행 전 옵티마이저(Optimizer)라는 최적화 도구에 의해 어떻게 데이터를 가장 효율적으로 처리할지, 즉 I/O를 최소화 하기위한 여러 방법을 검토하고 최적의 실행계획을 생성한다.

 이 실행계획을 생성하는 과정은 많은 자원을 소모하는 작업으로 여러 유저들 사이에서도 같은 작업을 수행할 때 실행계획을 재사용할 수 있도록 공유(캐싱)해두는데, Shared Pool의 Library Cache라는 영역에 공유되어 있다.

 

 당신이 수행한 명령의 실행계획이 누군가에 의해 수행되어 이미 존재한다면, 그대로 가져다 쓸 것이고 자원 소모를 최소화 한 결과가 된다. 이를 Soft Parse 라고 한다.

 

 그러나 최초로 실행한 명령이거나, 캐싱되어 있던 실행계획이 밀려나 Library  Cache에 없다면 어쩔 수 없이 옵티마이저가  무거운 작업을 수행 해야할 것이다. 이를 Hard Parse라 한다. Soft Parse일경우 아래 서술 할 최적화 과정 없이 바로 Execute 단계를 수행하게 된다.

 

 Hard Parse가 수행될 경우에는 옵티마이저는 다음과 같은 서브 엔진들에 의한 작업을 거쳐 최적 실행계획을 생성하게 된다. 

1) Query Transformer

 사용자의 SQL을 동일 결과를 내는 일반적이고 표준형태로 변환한다. 이를테면, A between B and C는 B<=A, C>=A로 변환된다. (정확한 예시가 아님)

2) Estimator

 오브젝트와 시스템 통계정보를 활용해 총 비용을 계산해본다.

3) Plan Generator

 후보 실행계획을 생성한다.

 

옵티마이저에 의해 실행계획이 생성되면 Row-Source Generator 엔진에 의해 SQL 엔진이 실행 가능한 코드로 포맷팅되고 SQL 엔진에 의해 실행(Execute) 된다.

 

2. Execute

 이 단계에서 고려될 대상은 해당하는 블럭이 Database Buffer Cache에 Caching 되어 있느냐 마느냐, 즉 메모리를 읽느냐 디스크를 읽느냐 하는 것이다.

캐싱되어 있다면 I/O가 일어날 필요 없이 Logical Read, 즉 Cache hit가 되어 사용자에게 결과를 반환할 것이고, 아니라면 Cache miss, 즉 디스크를 읽는 무거운 작업인 I/O가 발생하는 Physical Read가 수행된다.

 

 실행계획에 의해 방문할 블록이 선정되면, 해당 블럭이 Caching 되어 있는지에 대한 여부를 확인해야 하는데 모든 DB Buffer Cache를 전부 탐색하는 것은 아니고 내부 알고리즘으로 탐색할 수 있도록 Shared Pool 에서 관리하고 있다.

 

 Physical Read를 수행하게 되면 디스크에서 데이터를 가져와 DB Buffer Cache에 캐싱하는 작업까지 수행하게 된다.

 

3. Fetch (SELECT Only)

 DB Buffer Cache에서 데이터를 가져와 서버 프로세스에게 할당된 PGA에서 group by, order by와 같은 Sort 작업을 수행한 뒤 사용자에게 결과를 반환한다.