생계/튜닝2024. 12. 11. 01:19
반응형

1) 오라클에서 SQL 의 처리과정 

https://docs.oracle.com/en/database/oracle/oracle-database/19/tgsql/sql-processing.html#GUID-873A7B2C-CD17-428A-8AE2-5B08906E45FB

사용자가 SQL 을 실행하면 아래 1~ 3 까지의 파싱 단계를 거치게 된다. 

 1. syntax check : 문법적 오류 체크 (ex. select * form tab_a )

 2. semantic check : 존재하지 않는 테이블 조회 등

 3. shared pool check : 동일한 sql 이 shared pool 에 캐싱되어 있는지 확인 

이 과정을 거쳐 SQL 이 캐싱되어 있지 않는 것으로 확인되면 (library cache miss) 

4. 실행계획 생성 단계를 거쳐 

5. 최종적으로 실행을 하게 된다. 

이때 실행계획 생성과정에서 library cache, data dictionary cache 에 반복적으로 접근하고 이 과정에서 

latch 라는 lock 보다는 가벼운 잠금장치를 수없이 획득하는 과정을 거친다. 

 

2) 소프트 파싱 vs 하드 파싱

 - 소프트 파싱 (Soft Parsing) 

이미 만들어진 실행계획을 캐시에서 찾아 재사용하는 과정이다. 

Shared Pool의 Library Cache에 저장된 SQL 실행 계획을 공유하여 최적화 과정을 생략한다. ( 위에서 1,2,3 은 실행, 4,5 가 생략)

실행계획 생성과정이 cpu 를 많이 소모하는 과정이기 때문에 하드 파싱에 비해 더 빠르고 리소스를 절약할 수 있다.

 - 하드 파싱 (Hard Parsing)

 캐시에 SQL 이 존재하지 않아 (library cache miss) 새로운 실행 계획을 생성해야 할 때 발생. 

최적화 및 로우 소스 생성 단계까지 모두 거친 후에 SQL 이 실행된다. 



3) 소프트 파싱의 이점과 한계

소프트 파싱은 실행 계획을 반복적으로 생성하는 오버헤드를 줄여 성능을 향상 시켜주어 이롭다.

특히 OLTP 환경에서 동시 접속자가 많을 때 효과적. 그러나 항상 최선의 선택은 아니다.

사용자 입력값만 달라지는 SQL 은 다른 SQL ID 이 부여되어 하드파싱 비율이 올라가는데 이때 입력값을 

바인드 변수 처리하면 같은 SQL ID 로 처리되어 소프트 파싱으로 처리되는 비율이 높아지는 장점이 있다. 

하지만 이는 데이터의 분포와 상관없이 동일한 플랜을 적용하겠다는 의미이기 때문에,

skewed 데이터 분포를 보이는 컬럼에 대해서는 문제가 될수 있다. 

 

4) 바인드 Peeking의 역효과 예시

이에 대한 보완으로 오라클 9i 부터 바인드 피킹이란 것이 처음 등장했다.

바인드 변수를 사용하는 SQL 문장이 처음 실행될 때, 변수에 전달된 값을 옵티마이저가 '엿보고(peek)'

그 값을 기반으로 실행계획을 수립하는 기능.

그러나 이것은 다른 데이터 분포의 바인드변수가 들어오면 성능상 문제가 발생할수 있다. 

ex)  다음과 같은 테이블과 쿼리가 있다고 가정해보자 

SELECT * FROM 직원 WHERE 부서 = :dept

이 테이블에서 '영업부'는 전체 직원의 50%를 차지하고, 나머지 부서들은 각각 5% 미만의 직원을 가지고 있다.
 - 첫 실행 시 :dept에 '인사부'가 바인딩되었다면 => 옵티마이저는 인덱스 스캔을 선택합니다. 
 - 이 실행 계획이 캐시에 저장
 - 이후 '영업부'로 쿼리를 실행 => 캐시된 실행 계획(인덱스 스캔)을 사용
 - 하지만 영업부는 데이터의 50%를 차지하므로, 풀 테이블 스캔이 더 효율적 
이로 인해 '영업부' 쿼리의 성능이 크게 저하될 수 있습니다.

이런 부작용으로 보통은 "_OPTIM_PEEK_USER_BINDS" 파라미터가 false 로 사용

5) 소프트 파싱 한계에 대한 대안

1. 힌트 사용:
특정 쿼리에 대해 옵티마이저 힌트를 사용하여 원하는 실행 계획을 강제
SELECT /*+ FULL(직원) */ * FROM 직원 WHERE 부서 = :dept

2. 아웃라인 사용:
특정 쿼리에 대한 실행 계획을 고정
CREATE OUTLINE 직원_부서_조회 FOR
SELECT * FROM 직원 WHERE 부서 = :dept;

3. 적응적 커서 공유 활용:
Oracle 11g 이상에서는 적응적 커서 공유를 통해 바인드 변수 값에 따라 다른 실행 계획을 사용할 수 있다

아래에 따로 포스팅 해놓았다. 

적응적 커서 공유

4. 특정 SQL의 소프트 파싱 방지
SELECT /*+ NO_SHARED_CURSOR */ * FROM 직원 WHERE 부서 = :dept

5. CURSOR_SHARING (자동바인드 여부 제어) 파라미터 조정

세션 레벨에서 CURSOR_SHARING을 조정  
ALTER SESSION SET CURSOR_SHARING = EXACT;   -- 동일한 쿼리에 대해서 소프트파싱(default)
ALTER SESSION SET CURSOR_SHARING = FORCE;   -- 리터럴을 바인드로 바꿈. 


반응형
Posted by 돌고래트레이너