본문 바로가기

용어,개념

Cursor 에 대하여


    =================================================================================

      1. 공유커서 (Shared  Cursor)    : Library  Cache에 공유돼 있는 Shared SQL Area 

      2. 세션커서 (Session Cursor)   : Private SQL Area에 저장된 Cursor

      3. 애플리케이션 커서 (Application cursor) : 세션Cursor를 카리키는 핸들

    =================================================================================

 

1.  공유커서

 

      ◇ JAVA, VB, Pro*C, PL/SQL 등에서 SQL을 수행하면 Server Process는 해당 SQL이 Library Cache에 공유돼 있는지를

          먼저 확인한다.

      ◇ Library Cache에 공유돼 있는 Shared SQL Area를 'Cursor'라 한다.

 

 

2.  세션커서

 

      ◇ Library Cache에 공유돼 있는 Cursor를 실행할 떄, 우선 PGA영역에 메모리를 할당.
          이를 'Private SQL Area'라 한다. 

 

      ◇ Private SQL Area

          - Persistent Area : 바인드 변수 등을 저장하며 실행 종료 후 Cursor가 닫힐 떄 해제 된다

          - Runtime    Area : select문은 모든 record를 Fetch완료하거나 실행을 취소할 때 해제되지만, 

                                     insert, update, delete는 실행이 종료됨과 동시에 해제 된다.

 

      ◇ Shared SQL Area를 읽어서 실행하는데 필요한 정보들을 Private SQL Area에 담고,
          공유 Cursor를 가리키는 포인터를 유지하며,

          Cursor상태(open, bound, execute, close 등) 정보도 관리한다. 
          ⇒ 이러한 준비과정을 'Cursor를 오픈한다'라 표현한다.

 

      ◇ Cursor : PGA에 저장된 Cursor 정보(파싱된 SQL문, 문장을 수행하는데 필요한 기타 정보)

 

 

3.  애플리케이션 커서

 

      ◇ PGA에 있는 Cursor를 핸들링하려면 JAVA, VB, Pro*C, PL/SQL같은 클라이어트 애플리케이션에도
          리소스를 할당해야 하는데,
  이 또한 'Cursor'라는 용어를 사용한다.

 





 

 ▶  커서공유

 

      ◇ "Cursor를 공유한다" 표현에서 Cursor는 Library  Cache으 공유 Cursor를 일컫는다.

          Session Cursor, Application Cursor는 다른 Process와 공유할 수 없다.

 

      ◇ V$SQL

          - 실제 공유된 Cursor가 어떻게 반복·재사용되는지 확인.

          - Child Cursor 정보를 보여준다 (cf : v$sqlarea는 Parent Cursor 정보를 보여준다).

 

             ┌  parse_calls  : Library Cache에서 SQL Cursor를 찾으려는 요청 횟수  

             ├  loads           : 하드파싱을 거친 SQL 실행계획을 Library Cache에 적재한 횟수

             ├  executions   : SQL을 수행한 횟수

             └  invalidations : Cursor가 무효화된 횟수. Cursor가 참조하고 있는 오브젝트에 중요한 변화가 일어났음을 의미

                                      →Cursor가 무효화의 예 : Cursor가 참조하고 있던 오브젝트에 column이 삭제, 추가 되거나,

                                         새로운 index가 만들어지거나, 오브젝트 통계를 새로 수집하는 등의 DDL문이 수행되는 경우

 

      ◇ Cursor가 공유되려면 Cursor를 식별하는 키 값이 같아야 한다.

          Library Cache에서 Cursor를 식별하기 위해 사용하는 key 값은 'SQL문장 그 자체' 문자열이 이름 역할을 한다.

 

      ◇ V$SQL을 조회해 보면, sql_id 라는 별도의 식별자 column(10g부터)

           - sql_id와 sql_full text는 1:1로 대응되므로 SQL문 중간에 작은 공백문자 하나만 추가하더라도 
             서로 다른 SQL문장으로 인식해 새로운 sql_id를 발급 받게 된다. 
             ⇒  즉, Cursor가 공유되지 않는다.

                                                

 

 ▶  Child Cursor를 공유하지 못하는 경우

   

      ◇ Object LCO (stored Object)

          - 생성될 때부터 유일하게 식별 가능한 이름이 부여되므로 Child Object를 사용할 필요가 없다.

 

      ◇ 실행가능 LCO (Transient Object) = SQL Cursor

          - 이름을 따로 지정하지 않고 문장을 구성하는 전체 문자열 그대로가 LCO식별하는 이름.

                     ⇒  그래서, 전체 문자열은 같지만 다른 방식으로 실행해야하거나

                          파싱 시키마에 따라 다른 Object를 참조하는 상황에서는 Child Cursor가 필요

          - SQL마다 하나의 Parent Cursor를 가지며, 적어도 한개의 Child Cursor를 갖는다.

 

 

      ★ 하나의 SQL문장이 여러개 Child Cursor를 갖는 이유-------------------------------------------------------

           ① SQL에서 참조하는 Object명이 같지만 실행한 사용자에 따라 다른 Object를 가리킬 때

           ② 참조 Object가 변경돼 Cursor가 무효화되면 이후 그 Cursor를 처음 사용하려는 세션에 의해
               다시 하드파싱이 되야하는데, 특정 세션이 아직 기존 Cursor를 사용 중(Pin)일 때

           ③ 옵티마이저 모드를 비롯해 옵티마이저 관련 파라미터가 다를 때

           ④ 입력된 바인드 값의 길이가 크게 다를 때

           ⑤ NLS 파라미터를 다르게 설정했을 때

           ⑥ SQL 트레이스를 활성화 했을 떄

      ---------------------------------------------------------------------------------------------------------

          이는 새로운 Cursor가 왜 기존 Child Cursor와 공유되지 못했는지에 대한 이유가 되기도 한다(v$sql_shared_cursor).


  

 ▶  Parent Cursor를 공유하지 못하는 경우

 

      ◇ 의미적으로 같고 실행환경이 같은데도 Cursor를 공유하지 못해서 Parent Cursor 자체가 여러개 생성되는 경우

           ① 공백 문자 또는 줄바꿈

           ② 대소문자 구분

           ③ Table owner 명시

           ④ 주석(comment)

           ⑤ 옵티마이저 힌트 사용 (의도적인 것)

           ⑥ 조건절 비교 값 (Library Cache와 직접 관련이 큼)

                ⇒ 조건절에 바인드 변수를 사용하지 않고 서로 다른 Literal 값으로 문자열을 대체하는 경우!

 

 

참조 : 오라클 성능 고도화 원리와 해법1 (저자:조시형/출판사:비투엔컨설팅)

'용어,개념' 카테고리의 다른 글

Dynamic Performance Views  (0) 2010.09.02
Hidden Parameters  (0) 2010.09.02
ORACLE_BASE와 ORACLE_HOME는 무엇인고~?  (0) 2010.09.01
Initialization Parameter Files  (0) 2010.08.29
Dynamic Performance Views  (0) 2010.08.29