"커서 Cursor"의 두 판 사이의 차이
DB CAFE
(→라이브러리 캐시에 저장된 커서 조회) |
(→공유 가능한 커서 조건) |
||
28번째 줄: | 28번째 줄: | ||
# 일반적으로 SQL 구문의 텍스트가 완전히 동일하다면 여러 SQL 구문이 동일한 부모 커서를 공유함 | # 일반적으로 SQL 구문의 텍스트가 완전히 동일하다면 여러 SQL 구문이 동일한 부모 커서를 공유함 | ||
# 예외적으로 커서쉐어링 기능을 활성화 하면 SQL구문의 리터럴 값이 자동으로 바인드 변수로 치환되어 부모커서에 저장됨 | # 예외적으로 커서쉐어링 기능을 활성화 하면 SQL구문의 리터럴 값이 자동으로 바인드 변수로 치환되어 부모커서에 저장됨 | ||
− | 예제 1) TEXT가 다른 4건의 sql | + | 예제 1) TEXT가 다른 4건의 sql (2건이 같은 sql이므로 공유하는 경우) |
<source lang=sql> | <source lang=sql> | ||
SELECT * FROM t WHERE n = 1234; | SELECT * FROM t WHERE n = 1234; | ||
38번째 줄: | 38번째 줄: | ||
<source lang=sql> | <source lang=sql> | ||
select sql_id,sql_text,executions | select sql_id,sql_text,executions | ||
− | from v$ | + | from v$sqlarea |
− | where sql_text like '%1234; | + | where sql_text like '%1234'; |
SQL_ID SQL_TEXT EXECUTIONS | SQL_ID SQL_TEXT EXECUTIONS | ||
46번째 줄: | 46번째 줄: | ||
g93jtp6r34124 SELECT * FROM t WHERE n = 1234 1 | g93jtp6r34124 SELECT * FROM t WHERE n = 1234 1 | ||
ekekeq18ewqkr SELECT * FROM t WHERE n=1234 1 | ekekeq18ewqkr SELECT * FROM t WHERE n=1234 1 | ||
+ | </source> | ||
+ | |||
+ | 예제 2) 부모커서는 공유하지만 자식커서는 공유하지 못하는 경우 | ||
+ | * 옵티마이저 모드를 다르게 하여 테스트 | ||
+ | <source lang=sql> | ||
+ | alter session set optimizer_mod = all_rows; | ||
+ | SELECT count(*) FROM t; | ||
+ | |||
+ | COUNT(*) | ||
+ | -------- | ||
+ | 1000 | ||
</source> | </source> | ||
+ | <source lang=sql> | ||
+ | alter session set optimizer_mode = first_rows_1; | ||
+ | SELECT count(*) FROM t; | ||
+ | COUNT(*) | ||
+ | -------- | ||
+ | 1000 | ||
+ | </source> | ||
+ | |||
+ | * 1개의 부모커서(2254m1487jg50) 와 2개의 자식커서(0 과 1) 확인 | ||
+ | * 부모커서는 공유하지만 자식 커서는 공유하지 않음. | ||
+ | <source lang=sql> | ||
+ | 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 | ||
+ | </source> | ||
+ | * V$SQL_SHARED_CURSOR 뷰 조회 (어떤 불일치로 인해 여러개의 자식커서가 생성되었는지 확인) | ||
+ | * reason 컬럼은 clob 타입에 xml 이 저장됨. | ||
+ | <source lang=sql> | ||
+ | select optimizer_mode_mismatch,reason | ||
+ | from V$SQL_SHARED_CURSOR | ||
+ | where sql_id = '2254m1487jg50' | ||
+ | and child_number = 1; | ||
+ | |||
+ | OPTIMIZER_MODE_MISMATCH RESON | ||
+ | ----------------------- --------------- | ||
+ | Y <ChildNode>....... | ||
+ | </source> | ||
[[Category:oracle]] | [[Category:oracle]] |
2024년 1월 19일 (금) 17:49 기준 최신판
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>.......