행위

커서 Cursor

DB CAFE

thumb_up 추천메뉴 바로가기


  1. A cursor is a name or handle to a specific private SQL area.
  2. As shown in Figure 14-5, you can think of a cursor as a pointer on the client side and as a state on the server side.
  3. Because cursors are closely associated with private SQL areas, the terms are sometimes used interchangeably.

  1. 커서는 특정 개인(private) SQL 영역에 대한 이름 또는 핸들입니다.
    1. 핸들은 프로그램이 리소스에 액세스 할수 있도록 만들어 주는 메모리 구조
    2. 핸들은 클라이언트 메모리에 위치 하고 서버 프로세스에 할당된 메모리구조(SGA 내부의 라이브러리 캐시)를 참조
  2. 그림에서 볼 수 있듯이 커서는 클라이언트 측의 포인터와 서버 측의 상태로 생각할 수 있습니다.
  3. 커서는 서버측 개인용(private) SQL 영역과 밀접하게 연관되어 있기 때문에 이 용어는 때때로 같은 의미로 사용됩니다.
    1. 서버측 개인용 SQL영역에는 바인드 변수값과 쿼리 수행 상태 정보가 저장
    2. 서버측 개인용 SQL영역을 저장하는데 사용하는 세션 메모리를 UGA(User Global Area)라고 한다.

cncpt324.gif

1 라이브러리 캐시에 저장된 커서 조회[편집]

  • V$SQLAREA
  • V$SQL
  1. 부모커서 = sql_id 컬럼
  2. 자식커서 = child_number 컬럼


assignment 하드파싱을 피해야하는 이유 = 오라클이 공유가능한 커서(shared pool) 를 라이브러리 캐시에 저장하는 이유
  1. 실행 계획 생성작업은 CPU 부하가 많이 발생되는 작업
  2. 라이브러리 캐시에 저장되는 부모/자식 커서를 위해 shared pool 메모리가 소모됨
  3. shared pool은 모든 세션이 공유하기 때문에 메모리 할당시 반드시 래치(11g 부터는 뮤텍스)가 발생되는 직렬화 과정을 거쳐야함.

1.1 공유 가능한 커서 조건[편집]

  1. 일반적으로 SQL 구문의 텍스트가 완전히 동일하다면 여러 SQL 구문이 동일한 부모 커서를 공유함
  2. 예외적으로 커서쉐어링 기능을 활성화 하면 SQL구문의 리터럴 값이 자동으로 바인드 변수로 치환되어 부모커서에 저장됨

예제 1) TEXT가 다른 4건의 sql (2건이 같은 sql이므로 공유하는 경우)

SELECT * FROM t WHERE n = 1234;
select * from t where n = 1234;
SELECT   *  FROM t WHERE  n=1234;
SELECT * FROM t WHERE n = 1234;
  • 조회결과 3건 조회됨
select sql_id,sql_text,executions
  from v$sqlarea
 where sql_text like '%1234';

SQL_ID        SQL_TEXT                        EXECUTIONS
------------- ------------------------------  ----------
2254m1487jg50 select * from t where n = 1234           2
g93jtp6r34124 SELECT * FROM t WHERE n = 1234           1
ekekeq18ewqkr SELECT   *    FROM  t WHERE  n=1234      1

예제 2) 부모커서는 공유하지만 자식커서는 공유하지 못하는 경우

  • 옵티마이저 모드를 다르게 하여 테스트
alter session set optimizer_mod = all_rows;

SELECT count(*) FROM t; 

COUNT(*)
--------
    1000
alter session set optimizer_mode = first_rows_1;

SELECT count(*) FROM t; 

COUNT(*)
--------
    1000
  • 1개의 부모커서(2254m1487jg50) 와 2개의 자식커서(0 과 1) 확인
  • 부모커서는 공유하지만 자식 커서는 공유하지 않음.
select sql_id,child_number,optimizer_mode,plan_hash_value
  from v$sql
 where sql_text = 'SELECT count(*) FROM t';

SQL_ID        CHILD_NUMBER  OPTIMIZER_MODE PLAN_HASH_VALUE
------------- ------------- -----------------  ----------
2254m1487jg50 0             ALL_ROWS           2966233522 
2254m1487jg50 1             FIRST_ROWS         2966233522
  • V$SQL_SHARED_CURSOR 뷰 조회 (어떤 불일치로 인해 여러개의 자식커서가 생성되었는지 확인)
  • reason 컬럼은 clob 타입에 xml 이 저장됨.
select optimizer_mode_mismatch,reason 
  from V$SQL_SHARED_CURSOR 
 where sql_id = '2254m1487jg50'
   and child_number = 1;

OPTIMIZER_MODE_MISMATCH RESON
----------------------- ---------------
Y                       <ChildNode>.......