레이블이 LiteralSQL인 게시물을 표시합니다. 모든 게시물 표시
레이블이 LiteralSQL인 게시물을 표시합니다. 모든 게시물 표시

2021년 12월 19일 일요일

[오라클학원/오라클교육동영상]오라클커서공유, CURSOR_SHARING 파라미터, 커서란? 소프트파싱,하드파싱, Literal SQL, Bind SQL, 리터럴SQL, 바인드변수SQL

 [오라클학원/오라클교육동영상]오라클커서공유, CURSOR_SHARING 파라미터, 커서란? 소프트파싱,하드파싱, Literal SQL, Bind SQL, 리터럴SQL, 바인드변수SQL


오라클커서공유, CURSOR_SHARING 파라미터, 커서란? 소프트파싱,하드파싱, Literal SQL, Bind SQL, 리터럴SQL, 바인드변수SQLORACLE SQL 튜닝CURSOR_SHARING 파라미터ORACLE 19CCURSOR_SHARING 파라미터는 오라클 커서를 공유하는 방식을 셋팅하는데 기본값은 EXACT로 두 SQL문이 정확히 일치해야…

ojc.asia






CURSOR_SHARING 파라미터는 오라클 커서를 공유하는 방식을 셋팅하는데 기본값은 EXACT로 두 SQL문이 정확히 일치해야만 SQL 커서를 공유합니다. 

 

만약 PL/SQL에서 “select * from emp where deptno = 10” 이라는 SQL문과 “select * from emp where deptno = 20” 두 SQL문장이 사용되었다면 이는 서로 다른 SQL로 인식을 해서 각각 하드 파싱을 하고 쿼리 성능이 저하 됩니다. 이런식으로 작성된 SQL문을 Literal SQL문 이라고 합니다. 위 두 SQL문장을 동일한 SQL문장으로 인식시키기 위해서는(커서를 공유) CURSOR_SHARING 파라미터 값을 “FORCE”로 주시면 되고. 이는 실습을 통해 확인 해 보겠습니다.

 

다음 예제를 통해 리터럴 SQL과 바인드 변수 SQL 사용에 따른 하드파싱과 소프트 파싱의 차이에 대해서 알아 보세요~

 

–Shared Pool의 SQL Area를 클리어 합니다. 이후 실행되는 SQL문장은 하드파싱을 하게 됩니다.
ALTER SYSTEM FLUSH SHARED_POOL;

– DBMS_OUT 출력을 활성화 합니다. SQL Developer등에서 출력 결과를 확인할 수 있습니다.
SET SERVEROUTPUT ON;

– 리터럴 SQL을 사용한 예
DECLARE
  v_sql VARCHAR2(500);
  v_cnt NUMBER;
BEGIN
  FOR I IN 1..5 LOOP
    v_sql := 'SELECT /*+ LITERAL */ COUNT(*) FROM MYEMP1 
                  WHERE EMPNO = ' || i;
    DBMS_OUTPUT.PUT_LINE(v_sql);
    EXECUTE IMMEDIATE v_sql INTO v_cnt;
    DBMS_OUTPUT.PUT_LINE(v_cnt);
  END LOOP;
END;
/

– Shared Pool의 SQL Area에서 위에서 실행한 SQL문장의 개수 및 총실행 횟수를 조회 합니다. 5번 각각 하드 파싱 되었고 총 실행횟수도 1임을 확인 합니다.
SELECT SUBSTR(sql_text,1,60) "SQL", COUNT(*),
        SUM(EXECUTIONS) "총실행횟수"
 FROM V$SQLAREA
 WHERE SQL_TEXT LIKE '%LITERAL%'
 GROUP BY SUBSTR(sql_text,1,60)
 HAVING COUNT(*) > 0
 ORDER BY 2;
 
 
 ALTER SYSTEM FLUSH SHARED_POOL;
 
– 바인드 변수 SQL형태로 작성된 예문 입니다.
 DECLARE
  v_sql VARCHAR2(500);
  v_cnt NUMBER;
BEGIN
  FOR i IN 1..5 LOOP
    v_sql := 'SELECT /*+ BIND */ COUNT(*) FROM MYEMP1 
                  WHERE EMPNO = :1';
    DBMS_OUTPUT.PUT_LINE(V_SQL);
    EXECUTE IMMEDIATE v_sql INTO v_cnt USING i;
    DBMS_OUTPUT.PUT_LINE(v_cnt);
  END LOOP;
END;
/

– Shared Pool의 SQL Area에서 위에서 실행한 SQL문장의 개수 및 총실행 횟수를 조회 합니다. 1번 하드 파싱 되었고 총 실행횟수가 5임을 확인 합니다.
SELECT SUBSTR(sql_text,1,60) "SQL", COUNT(*),
        SUM(EXECUTIONS) "총실행횟수"
 FROM V$SQLAREA
 WHERE SQL_TEXT LIKE '%BIND%'
 GROUP BY SUBSTR(sql_text,1,60)
 HAVING COUNT(*) > 0
 ORDER BY 2;



Oracle 8.1.6에서 소개된 CURSOR_SHARING 변수는 각각의 문장들에 대해 Bind 변수로 처리하지 않더라도 내부적으로 바인드 변수로 처리하여 각각의 Cursor에 대해 공유가 가능하도록 했습니다. 실제 이 기능은 Bind 변수를 쓰는 것보다는 빠르지 않지만 Literal SQL문을 이용하는 것보다 20~30% 성능 향상이 있는 것으로 검증 되었으며 오라클12C이후 사용가능한 두 파라미터는 EXACT, FORCE이다.

 

오라클11g,12C, 19C에서 CURSOR_SHARING 파라미터의 기본값은 EXACT인데 기본값이 아닌 FORCE인 경우 SQL문장이 리터럴 SQL 형태로 작성되었다면 시스템에서 생성한 바인드 변수(:SYS_B_0)로 리터럴 값을 자동 변형 한다.

 

CURSOR_SHARING 값이 기본값(EXACT)이 아닌 경우 즉 FORCE인 경우 아래와 같은 절차로 SQL구문을 파싱한다.

 

“select * from emp where deptno = 10” 이라는 SQL문장이 이미 실행되었고 “select * from emp where deptno = 20” 문장을 실행한다고 했을 때

 

  1. Shared Pool 안에서 공백, 대소문자까지 완벽하게 동일한 SQL 문장이 있는지 검사한다. 만약 동일한 SQL문장이 있으면 파싱트리 및 실행계획을 공유해서 사용하고 4번으로, 없다면 다음 2번을 수행한다.
  2. Shared Pool에서 유사한 SQL문장을 찾는다. (예를 들면 where절의 상수값만 다른 경우), 만약 유사한 SQL문장이 없다면 Hard Parsing을 수행하여 파싱트리, 실행계획을 만들고 4번으로, 이미 있다면 다음 3번을 수행한다.
  3. 남은 과정은 실행한 SQL문장(where deptno = 20)의 실행 계획이 상수값만 다른 상태로 존재하는 처음에 실행된 SQL문장(where deptno = 10)의 실행계획을 공유할 수 있는지를 확인하는 것인데 만약 공유 불가능하다면 Hard Parsing을 적용하여 새로운 실행계획을 만들고 공유가능 하다면 실행계획을 공유한 다음 4번을 진행한다.
  4. 공유 SQL Area에 SQL문장 및 파싱트리, 실행계획을 공유시킵니다.
  5. 실행 계획대로 로우 소스 트리(파싱 트리)에 따라 SQL문을 실행 합니다.

 

위에서 작성한 실습에 이어서 CURSOR_SHARING 파라미터를 사용하여 실습합니다.

 

– 상수값이 하드코딩된 리터럴 SQL 구문을 커서가 공유될 수 있도록 셋팅 합니다.
– CURSOR_SHARING 파라미터의 기본값은EXACT로 리터럴 SQL 형태로 작성된 구문은 sQL 커서를 공유할 수 없습니다(동일한 SQL로 인식되지 않습니다)
ALTER SESSION SET CURSOR_SHARING = FORCE;

–Shared Pool의 SQL Area를 클리어 합니다. 이후 실행되는 SQL문장은 하드파싱을 하게 됩니다.
ALTER SYSTEM FLUSH SHARED_POOL;

– 리터럴 SQL을 사용하여 SQL을 작성 합니다.
DECLARE
  v_sql VARCHAR2(500);
  v_cnt NUMBER;
BEGIN
  FOR I IN 1..5 LOOP
    v_sql := 'SELECT /*+ LITERAL */ COUNT(*) FROM MYEMP1 
                  WHERE EMPNO = ' || i;
    DBMS_OUTPUT.PUT_LINE(v_sql);
    EXECUTE IMMEDIATE v_sql INTO v_cnt;
    DBMS_OUTPUT.PUT_LINE(v_cnt);
  END LOOP;
END;
/

– Shared Pool의 SQL Area에서 위에서 실행한 SQL문장의 개수 및 총실행 횟수를 조회 합니다. 1번 하드 파싱 되었고 총 실행횟수가 5임을 확인 합니다. 커서가 공유되었습니다!
SELECT SUBSTR(sql_text,1,60) "SQL", COUNT(*),
        SUM(EXECUTIONS) "총실행횟수"
 FROM V$SQLAREA
 WHERE SQL_TEXT LIKE '%LITERAL%'
 GROUP BY SUBSTR(sql_text,1,60)
 HAVING COUNT(*) > 0
 ORDER BY 2;

#오라클커서, #커서공유, #CURSOR_SHARING, #커서란?, #소프트파싱,#하드파싱, #LiteralSQL, #Bind SQL, #리터럴SQL, #바인드변수SQL, #오라클교육, #오라클동영상, #오라클학원, 오라클커서, 커서공유, CURSOR_SHARING, 커서란?, 소프트파싱,하드파싱, LiteralSQL, Bind SQL, 리터럴SQL, 바인드변수SQL, 오라클교육, 오라클동영상, 오라클학원,  



(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...