커서 Cursor
DB CAFE
thumb_up 추천메뉴 바로가기
- DBA { Oracle DBA 명령어 > DBA 초급 과정 > DBA 고급 과정 }
- 튜닝 { 오라클 튜닝 목록 }
- 모델링 { 데이터 모델링 가이드 }
- A cursor is a name or handle to a specific private SQL area.
- 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.
- Because cursors are closely associated with private SQL areas, the terms are sometimes used interchangeably.
- 커서는 특정 개인(private) SQL 영역에 대한 이름 또는 핸들입니다.
- 핸들은 프로그램이 리소스에 액세스 할수 있도록 만들어 주는 메모리 구조
- 핸들은 클라이언트 메모리에 위치 하고 서버 프로세스에 할당된 메모리구조(SGA 내부의 라이브러리 캐시)를 참조
- 그림에서 볼 수 있듯이 커서는 클라이언트 측의 포인터와 서버 측의 상태로 생각할 수 있습니다.
- 커서는 서버측 개인용(private) SQL 영역과 밀접하게 연관되어 있기 때문에 이 용어는 때때로 같은 의미로 사용됩니다.
- 서버측 개인용 SQL영역에는 바인드 변수값과 쿼리 수행 상태 정보가 저장
- 서버측 개인용 SQL영역을 저장하는데 사용하는 세션 메모리를 UGA(User Global Area)라고 한다.
1 라이브러리 캐시에 저장된 커서 조회[편집]
- V$SQLAREA
- V$SQL
- 부모커서 = sql_id 컬럼
- 자식커서 = child_number 컬럼
assignment 하드파싱을 피해야하는 이유 = 오라클이 공유가능한 커서(shared pool) 를 라이브러리 캐시에 저장하는 이유
- 실행 계획 생성작업은 CPU 부하가 많이 발생되는 작업
- 라이브러리 캐시에 저장되는 부모/자식 커서를 위해 shared pool 메모리가 소모됨
- shared pool은 모든 세션이 공유하기 때문에 메모리 할당시 반드시 래치(11g 부터는 뮤텍스)가 발생되는 직렬화 과정을 거쳐야함.
1.1 공유 가능한 커서 조건[편집]
- 일반적으로 SQL 구문의 텍스트가 완전히 동일하다면 여러 SQL 구문이 동일한 부모 커서를 공유함
- 예외적으로 커서쉐어링 기능을 활성화 하면 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>.......