Bind Variable과 실행계획: Bind Peeking·Adaptive Cursor Sharing
Bind 변수의 Cursor 공유 이점과 Data Skew 부작용을 Bind Peeking·ACS·CURSOR_SHARING으로 구분합니다.
핵심 요약
Bind Variable은 값이 달라도 SQL Text를 일정하게 유지하여 Parent Cursor 공유와 Hard Parse 감소에 도움을 줍니다.
SELECT order_id,
order_date
FROM orders
WHERE customer_id = :customer_id;
그러나 다음 두 문제는 구분해야 합니다.
Literal SQL이 값마다 다른 SQL Text로 생성됨
→ Parent Cursor와 SQL_ID가 증가
→ Hard Parse·Shared Pool 사용 증가
Bind SQL이지만 값별 데이터 분포가 크게 다름
→ 하나의 실행계획이 모든 값에 적합하지 않을 수 있음
→ Bind Peeking과 Adaptive Cursor Sharing으로 보완 가능
핵심 개념은 다음과 같습니다.
| 개념 | 의미 |
|---|---|
| Bind Peeking | Optimizer가 관련 Hard Parse에서 Bind 값을 참고해 Selectivity·Cardinality와 실행계획을 결정할 수 있는 기능 |
| Bind-Sensitive Cursor | Bind 값에 따라 최적 Plan이 달라질 가능성을 인식하고 실행 특성을 관찰하는 Cursor |
| Bind-Aware Cursor | 현재 Bind 값의 선택도 범위에 맞는 Child Cursor와 Plan을 사용할 수 있는 상태 |
| Adaptive Cursor Sharing | 하나의 Bind SQL이 값별 선택도에 따라 여러 Child Plan을 사용할 수 있게 하는 기능 |
| Cursor Merging | 새 Child의 Plan이 기존 Child와 같으면 선택도 범위를 합쳐 불필요한 Cursor를 줄이는 동작 |
| CURSOR_SHARING=FORCE | Literal을 System-Generated Bind로 치환하여 유사 SQL의 공유 가능성을 높이는 전술적 설정 |
Bind Variable
→ SQL Text 공유 가능성 향상
Prepared Statement·Cursor 재사용
→ Parse Call 자체 감소
Adaptive Cursor Sharing
→ Bind 선택도 범위별 Plan 품질 보완
이 이론의 범위
이 이론은 SQLP의
SQL 옵티마이저 → SQL 공유 및 재사용범위에서 Bind Variable, Bind Peeking, Adaptive Cursor Sharing과CURSOR_SHARING의 관계를 다룹니다. Histogram 생성 방법, Parent·Child Cursor 공유 실패 Column 전체 목록과 실행계획별 인덱스 내부 동작은 후속 이론에서 다룹니다.
학습 목표
이 이론을 학습한 뒤에는 다음 내용을 설명할 수 있어야 합니다.
- Literal SQL과 Bind SQL의 Parent Cursor 생성 차이를 설명한다.
- Application Bind와 Prepared Statement 재사용의 역할을 구분한다.
- Bind Variable의 성능·보안 이점과 실행계획 측면의 한계를 설명한다.
- Data Skew가 값별 Access Path 선택에 미치는 영향을 설명한다.
- Bind Peeking이 발생할 수 있는 시점과 Plan 재사용 관계를 설명한다.
- Histogram이 Bind Cardinality 추정에 주는 도움과 한계를 설명한다.
- Bind-Sensitive Cursor가 되는 기본 조건을 설명한다.
- Bind-Aware Cursor의 선택도 범위 재사용과 새 Child 생성 흐름을 설명한다.
- Cursor Merging이 필요한 이유를 설명한다.
- ACS와
CURSOR_SHARINGParameter가 독립적인 기능인 이유를 설명한다. V$SQL,V$SQL_CS_SELECTIVITY,V$SQL_CS_STATISTICS,V$SQL_CS_HISTOGRAM의 역할을 구분한다.- Literal 폭증과 Bind Plan Skew를 서로 다른 문제로 진단한다.
1. Literal SQL과 Bind SQL
1.1 Literal SQL
다음 SQL은 조회 값만 다릅니다.
SELECT *
FROM orders
WHERE customer_id = 101;
SELECT *
FROM orders
WHERE customer_id = 205;
SELECT *
FROM orders
WHERE customer_id = 930;
기본 CURSOR_SHARING=EXACT 환경에서는 SQL Text가 서로 다르므로 별도 Parent Cursor와 SQL_ID가 생성될 수 있습니다.
Literal 101 → Parent A
Literal 205 → Parent B
Literal 930 → Parent C
값과 사용자 수가 많아질수록 다음 문제가 커질 수 있습니다.
- Parent Cursor 증가
- Hard Parse와 Parse CPU 증가
- Shared Pool 메모리 사용 증가
- Library Cache 동시성 비용 증가
- SQL 모니터링과 관리 복잡성 증가
1.2 Bind SQL
Bind Variable은 값이 들어갈 위치를 Placeholder로 두고 실행 시 값을 전달합니다.
SELECT *
FROM orders
WHERE customer_id = :customer_id;
101 ─┐
205 ─┼─→ 동일 SQL Text → 같은 Parent Cursor 후보
930 ─┘
Application에서 Bind API와 Prepared Statement를 올바르게 사용하면 하나의 SQL Text와 Cursor를 여러 값에 재사용할 수 있습니다.
2. Application Bind의 이점과 한계
| 관점 | 이점 | 함께 확인할 한계 |
|---|---|---|
| Parent Cursor 공유 | 값이 달라도 SQL Text를 일정하게 유지 | 대소문자·공백·주석·Bind 이름과 SQL 생성 방식도 일관되어야 함 |
| Parse 비용 | Hard Parse와 Shared Pool 중복을 줄일 수 있음 | Application이 매번 Parse하면 Soft Parse 비용은 남을 수 있음 |
| Child Cursor 공유 | Bind Type·Length가 일관되면 공유 가능성 증가 | Bind Metadata와 Optimizer 환경이 호환되어야 함 |
| 보안 | 값과 SQL 구조를 Bind API로 분리하여 SQL Injection 위험을 줄임 | CURSOR_SHARING=FORCE는 이미 조립된 SQL을 Parse 시 치환하므로 보안 해결책이 아님 |
| 실행계획 | 검증된 Plan을 재사용할 수 있음 | Data Skew가 크면 한 Plan이 모든 값에 적합하지 않을 수 있음 |
Bind Variable과 Statement 재사용은 역할이 다릅니다.
Bind Variable
→ 값 변화로 SQL Text가 달라지는 문제를 줄임
Prepared Statement·Cursor 재사용
→ Parse Once·Execute Many 구조로 Parse Call 자체를 줄임
Bind만 사용하고 실행할 때마다 Statement를 새로 준비하면 기존 Plan을 재사용하더라도 Soft Parse가 반복될 수 있습니다.
3. Data Skew가 실행계획 선택을 어렵게 만드는 이유
ORDERS.STATUS의 분포가 다음과 같다고 가정합니다.
| STATUS | 행 비율 |
|---|---|
COMPLETE | 99% |
ERROR | 1% |
SQL은 하나입니다.
SELECT order_id,
customer_id,
order_date
FROM orders
WHERE status = :status;
값별로 유리한 Access Path가 달라질 수 있습니다.
| Bind 값 | 예상 행 수 | 유리할 수 있는 Access Path |
|---|---|---|
ERROR | 전체의 약 1% | Index Range Scan 후 소량 Table Access |
COMPLETE | 전체의 약 99% | Full Table Scan 또는 대량 처리 경로 |
ERROR
→ 적은 Index Entry와 ROWID 처리
→ Index Access가 유리할 가능성
COMPLETE
→ 대량 Index Entry와 Table Access by ROWID
→ Full Table Scan이 유리할 가능성
같은 Bind SQL에 하나의 Plan만 계속 사용하면 특정 값에서는 빠르지만 다른 값에서는 매우 느릴 수 있습니다.
4. Bind Peeking
Bind Peeking은 Optimizer가 관련 Hard Parse에서 사용자 Bind 값을 참고해 Predicate의 Selectivity와 Cardinality를 추정하는 기능입니다.
Hard Parse
→ Bind 값 Peeking 가능
→ 값의 Selectivity·Cardinality 추정
→ 실행계획 생성
→ Child Cursor에 저장
중요한 기준은 다음과 같습니다.
- Bind 값을 매 Execute마다 다시 Peeking하는 것은 아닙니다.
- Soft Parse로 기존 Child Cursor를 재사용하면 기존 Plan을 사용합니다.
- 새로운 Child Cursor를 만드는 Hard Parse가 발생하면 그 시점의 Bind 값이 다시 Plan 생성에 사용될 수 있습니다.
- Bind Peeking이 모든 Bind SQL에 항상 적용되는 것은 아닙니다.
4.1 첫 Plan이 희소값에 맞춰진 경우
첫 Hard Parse Bind = ERROR
→ 소량 행으로 추정
→ Index Plan 선택 가능
이후 Bind = COMPLETE
→ 기존 Index Plan 재사용 가능
→ 대량 ROWID Table Access로 느려질 수 있음
4.2 첫 Plan이 인기값에 맞춰진 경우
첫 Hard Parse Bind = COMPLETE
→ 대량 행으로 추정
→ Full Scan Plan 선택 가능
이후 Bind = ERROR
→ 소량 조회에도 Full Scan을 사용할 수 있음
Bind Peeking은 최초 Plan을 값에 맞게 만들 수 있지만 그 Plan이 모든 후속 Bind에 최적이라는 보장은 없습니다.
5. Histogram과 Bind Peeking
Histogram은 Column 값의 빈도 차이를 표현하는 통계정보입니다.
Histogram 없음 또는 분포 정보 부족
→ NDV와 균등 분포 가정 중심
→ 인기값과 희소값의 차이를 충분히 반영하지 못할 수 있음
Histogram 존재 + Hard Parse에서 Bind Peeking
→ 현재 Bind 값의 빈도 차이를 더 구체적으로 추정 가능
다만 다음 사항을 구분해야 합니다.
- Histogram은 값별 Selectivity 추정에 도움을 줍니다.
- Histogram이 있다고 한 Child Plan이 모든 값에 적합해지는 것은 아닙니다.
- Histogram은 Bind-Sensitive Cursor의 필수 조건으로 단정할 수 없습니다.
- ACS는 실행 결과를 관찰해 값별 Plan 필요성을 판단합니다.
Histogram의 유형과 생성·관리 방법은 통계정보 이론에서 다룹니다.
6. Bind-Sensitive Cursor
Bind-Sensitive Cursor는 Bind 값에 따라 최적 Plan이 달라질 가능성이 있다고 Oracle이 판단하여 실행 특성을 관찰하는 Cursor입니다.
대표적인 판단 조건은 다음과 같습니다.
- Optimizer가 Bind 값을 Peeking하여 Cardinality를 계산함
- Bind가 등치 또는 범위 Predicate에 사용됨
- Bind 개수와 형태가 내부 제한을 만족함
Bind-Sensitive
→ 아직 여러 Plan이 확정된 상태가 아님
→ 서로 다른 Bind 실행의 Row 수와 자원 사용을 관찰
V$SQL.IS_BIND_SENSITIVE = 'Y'로 확인할 수 있습니다.
Bind-Sensitive라는 사실만으로 이미 여러 실행계획을 사용한다고 판단하면 안 됩니다.
7. Bind-Aware Cursor와 Adaptive Cursor Sharing
여러 Bind 값의 실행 결과가 크게 다르고 다른 Plan이 유리하다고 판단되면 Cursor가 Bind-Aware 상태가 될 수 있습니다.
Bind-Sensitive 상태
→ 여러 Bind 값의 실행 통계 관찰
→ Cardinality와 Data Access Pattern 차이가 큼
→ Bind-Aware 전환 가능
Bind-Aware Cursor는 새 Bind 값의 선택도를 기존 Child Cursor의 유효 범위와 비교합니다.
새 Bind 값으로 Parse 요청
→ Bind Selectivity 계산
→ 적합한 기존 Child 범위 확인
├─ 범위 일치: 기존 Child Plan 재사용
└─ 범위 불일치: Hard Parse 후 새 Child Plan 생성 가능
전환 과정에서 최초 Cursor가 IS_SHAREABLE='N'으로 표시되어 이후 Aging Out 대상이 될 수 있습니다. 이는 Bind-Aware 상태를 만들기 위한 일시적인 전환 비용일 수 있습니다.
7.1 모든 Bind 값마다 새 Child가 생성되지는 않는다
Oracle은 값 자체가 아니라 선택도 범위와 Plan 적합성을 중심으로 기존 Child를 찾습니다.
희소값 선택도 범위
→ Index Plan Child 재사용
인기값 선택도 범위
→ Full Scan Plan Child 재사용
새 Bind 값의 선택도가 기존 범위에 포함되면 Hard Parse 없이 기존 Plan을 재사용할 수 있습니다. 따라서 Bind 값 수에 비례해 Child가 계속 증가하는 구조는 아닙니다.
8. Cursor Merging
Bind-Aware Cursor가 새 Bind 값을 위해 Hard Parse했지만 새 Plan이 기존 Child Plan과 같을 수 있습니다.
새 Bind 범위
→ 새 Child와 Plan 생성
→ 기존 Child의 Plan과 동일
→ 선택도 범위를 합침
→ 중복 Child를 Not Shareable 처리
이를 Cursor Merging이라고 합니다.
Cursor Merging의 목적은 다음과 같습니다.
- 같은 Plan을 사용하는 선택도 범위를 하나로 통합
- Library Cache의 불필요한 Child Cursor 감소
- 새로운 Bind 값에서 기존 Child를 재사용할 수 있는 범위 확대
IS_SHAREABLE='N'인 과거 Child가 보이더라도 ACS 전환과 Cursor Merging 과정인지 함께 확인해야 합니다.
9. ACS와 CURSOR_SHARING은 서로 다른 기능이다
9.1 CURSOR_SHARING
| 설정 | 의미 |
|---|---|
EXACT | SQL Text가 동일한 문장만 Cursor 공유를 허용하는 기본값 |
FORCE | Literal을 System-Generated Bind로 치환하여 유사 SQL의 공유 가능성을 높임 |
CURSOR_SHARING=FORCE는 Literal SQL 폭증을 줄이는 전술적 방법이지만 다음 한계가 있습니다.
- Parse Call 자체는 남습니다.
- 유사 SQL을 찾기 위한 Soft Parse 작업이 추가될 수 있습니다.
- 유용한 Literal 정보까지 치환되어 Plan 품질이 나빠질 수 있습니다.
- 모든 문장이 반드시 하나의 Cursor로 합쳐지는 것은 아닙니다.
- SQL Injection 문제를 해결하지 않습니다.
- Application Bind를 대신하는 영구 설계로 권장되지 않습니다.
근본 해결은 Application에서 사용자 정의 Bind를 사용하고 SQL Text와 Statement 수명주기를 관리하는 것입니다.
9.2 ACS와의 관계
Adaptive Cursor Sharing은 CURSOR_SHARING Parameter와 독립적입니다.
CURSOR_SHARING
→ Literal SQL을 얼마나 공유 가능한 Text로 처리할지 결정
Adaptive Cursor Sharing
→ Bind가 있는 SQL에서 현재 Bind 선택도에 적합한 Child Plan을 선택
ACS는 다음 SQL에 모두 적용될 수 있습니다.
- Application이 작성한 사용자 Bind SQL
CURSOR_SHARING=FORCE가 만든 System-Generated Bind SQL
Bind가 없는 Literal-only SQL에는 ACS가 적용되지 않습니다.
10. ACS 진단 View
10.1 V$SQL: Child 상태와 Plan 사용량
SELECT sql_id,
child_number,
plan_hash_value,
executions,
is_bind_sensitive,
is_bind_aware,
is_shareable,
buffer_gets,
cpu_time,
elapsed_time
FROM v$sql
WHERE sql_id = :sql_id
ORDER BY child_number;
확인 순서는 다음과 같습니다.
- Child Cursor는 몇 개인가?
- Child별
PLAN_HASH_VALUE가 다른가? IS_BIND_SENSITIVE,IS_BIND_AWARE가Y인가?IS_SHAREABLE='N'인 과거 Child가 존재하는가?- 각 Child의
EXECUTIONS와 실행당 자원 사용은 어떠한가?
실행당 비용을 비교합니다.
SELECT child_number,
plan_hash_value,
executions,
ROUND(buffer_gets / NULLIF(executions, 0), 1) AS gets_per_exec,
ROUND(cpu_time / NULLIF(executions, 0) / 1000, 1) AS cpu_ms_per_exec,
ROUND(elapsed_time / NULLIF(executions, 0) / 1000, 1) AS elapsed_ms_per_exec,
is_bind_sensitive,
is_bind_aware,
is_shareable
FROM v$sql
WHERE sql_id = :sql_id
ORDER BY child_number;
10.2 V$SQL_CS_SELECTIVITY: Child의 선택도 범위
SELECT sql_id,
child_number,
predicate,
range_id,
low,
high
FROM v$sql_cs_selectivity
WHERE sql_id = :sql_id
ORDER BY child_number, range_id;
이 View는 Extended Cursor Sharing에서 각 Child가 공유될 수 있는 Bind Predicate의 선택도 Low·High 범위를 보여 줍니다.
10.3 V$SQL_CS_STATISTICS: Bind-Aware 판단용 실행 통계
V$SQL_CS_STATISTICS는 Oracle이 Bind-Aware 여부를 판단할 때 참고하는 표본 실행의 처리 행 수, Buffer Gets와 CPU 정보 등을 요약합니다.
확인할 수 있는 대표 내용은 다음과 같습니다.
- Bind Set이 Cursor 생성에 사용되었는지
- 처리한 Row 수
- Buffer Gets
- CPU 사용량
10.4 V$SQL_CS_HISTOGRAM: 실행 이력 분포
V$SQL_CS_HISTOGRAM은 ACS가 Extended Cursor Sharing을 활성화할지 판단할 때 사용하는 실행 횟수의 Bucket 분포를 보여 줍니다.
Child Cursor가 여러 개라는 사실만으로 ACS라고 단정하면 안 됩니다. Bind Metadata·Optimizer 환경·권한·객체 차이도 Child 증가 원인이 될 수 있으므로
V$SQL_SHARED_CURSOR와 함께 확인합니다.
11. 문제 유형별 대응 방향
11.1 Literal SQL 폭증
현상
→ 유사 SQL이 여러 SQL_ID로 생성
→ 각 Parent의 VERSION_COUNT는 작을 수 있음
개선
→ Application Bind API 적용
→ SQL Text 생성 규칙 통일
→ Prepared Statement 재사용
→ 필요 시 FORCE를 임시·Session 범위에서 검증
11.2 Bind SQL의 값별 성능 편차
현상
→ 한 SQL_ID 아래 여러 Child와 Plan
→ Bind 값별 평균 Buffer·Elapsed 차이
확인
→ Data Skew·Histogram
→ Bind Peeking Plan
→ IS_BIND_SENSITIVE·IS_BIND_AWARE
→ Selectivity Range
→ Child별 실제 사용량
11.3 불필요한 Child Cursor 증가
현상
→ 같은 Plan Hash의 Child가 많이 생성
→ BIND_MISMATCH·환경 차이 발생
개선
→ Bind Type·Length·Character Set 통일
→ Connection Pool Session 설정 통일
→ V$SQL_SHARED_CURSOR로 ACS 이외의 원인 분리
12. 자주 혼동하는 판단과 정확한 기준
| 혼동하기 쉬운 판단 | 정확한 기준 |
|---|---|
| Bind Variable이면 항상 하나의 Child만 사용한다 | ACS와 호환성 차이로 여러 Child가 존재할 수 있다 |
| Bind Peeking은 매 Execute마다 수행된다 | 관련 Hard Parse에서 수행되며 Soft Parse는 기존 Plan을 재사용한다 |
| 첫 번째 Bind 값만 영구히 Plan을 결정한다 | ACS가 실행 결과를 관찰해 선택도 범위별 Plan을 만들 수 있다 |
| Histogram이 있어야만 Bind-Sensitive가 된다 | Histogram은 추정에 도움을 주지만 유일한 필수 조건은 아니다 |
| Bind-Sensitive이면 여러 Plan을 이미 사용한다 | 값별 Plan 필요성을 관찰하는 단계다 |
| Bind-Aware이면 모든 Bind 값마다 Child를 만든다 | 기존 선택도 범위를 재사용하고 같은 Plan은 Cursor Merging할 수 있다 |
| Child가 여러 개면 모두 ACS다 | Bind Metadata와 환경 공유 실패도 확인해야 한다 |
| ACS와 CURSOR_SHARING은 같은 기능이다 | ACS는 Bind별 Plan 선택, CURSOR_SHARING은 SQL Text 공유 정책이다 |
| FORCE는 Parse Call도 제거한다 | Parent 공유와 Hard Parse는 줄일 수 있지만 Parse 요청은 남는다 |
| FORCE를 사용하면 SQL Injection이 해결된다 | 안전한 Application Bind API가 필요하다 |
13. 핵심 정리
Literal SQL 폭증
→ 여러 SQL Text와 Parent Cursor 문제
Application Bind
→ SQL Text 공유와 보안 개선
Bind Peeking
→ 관련 Hard Parse에서 현재 Bind 값으로 최초 Plan 추정
Bind-Sensitive
→ 값별 성능 차이를 관찰
Bind-Aware
→ 선택도 범위별 Child Plan 사용
Cursor Merging
→ 같은 Plan의 선택도 범위를 통합
CURSOR_SHARING=FORCE
→ Literal을 System Bind로 치환하는 임시 완화책
→ ACS와 독립적인 기능
가장 중요한 진단 기준은 다음과 같습니다.
유사 SQL이 여러 SQL_ID로 나뉘는가?
→ Literal·SQL Text 공유 문제
한 SQL_ID 아래 값별 Plan과 비용이 다른가?
→ Bind Peeking·Data Skew·ACS 문제
같은 Plan Child가 불필요하게 많은가?
→ Bind Metadata·환경 공유 실패 문제
개념 확인 문제
문제를 누르면 바로 아래에서 정답과 해설을 확인할 수 있습니다.
01Literal SQL과 Application Bind SQL이 Parent Cursor 생성에 미치는 차이를 설명하시오.
Literal SQL과 Application Bind SQL
- Literal 값이 SQL Text에 직접 포함되면 값마다 서로 다른 Text와 SQL_ID가 생성되어 Parent Cursor가 증가할 수 있습니다.
- Bind SQL은 값 위치를 Placeholder로 유지하므로 여러 값이 같은 SQL Text와 Parent Cursor 후보를 사용할 수 있습니다.
02Bind Variable과 Prepared Statement 재사용이 각각 줄이는 비용을 설명하시오.
Bind와 Statement 재사용의 역할
- Bind Variable은 값 차이로 SQL Text가 달라지는 문제를 줄여 Parent Cursor 공유와 Hard Parse 감소에 도움을 줍니다.
- Prepared Statement·Cursor 재사용은 Parse Once·Execute Many 구조로 Parse Call과 Soft Parse 자체를 줄입니다.
- Bind만 사용하고 매번 Statement를 새로 준비하면 Soft Parse는 반복될 수 있습니다.
03Data Skew가 큰 Bind Predicate에서 하나의 Plan이 모든 값에 적합하지 않은 이유를 설명하시오.
Data Skew와 하나의 Plan 한계
- 값별 Selectivity와 Cardinality가 크게 다르면 필요한 작업량도 달라집니다.
- 희소값에는 Index Range Scan, 인기값에는 Full Table Scan이 유리할 수 있으므로 하나의 Plan을 모두에게 적용하면 특정 값에서 Random Access나 불필요한 Full Scan이 발생할 수 있습니다.
04Bind Peeking이 발생할 수 있는 시점과 Soft Parse에서의 Plan 재사용 관계를 설명하시오.
Bind Peeking과 Plan 재사용
- Bind Peeking은 Optimizer가 관련 Hard Parse에서 Bind 값을 참고해 Cardinality와 Plan을 만드는 기능입니다.
- 매 Execute마다 수행되는 것이 아닙니다.
- Soft Parse로 호환 Child를 찾으면 기존 Plan을 재사용합니다.
- 새 Child를 만드는 Hard Parse가 발생하면 그 시점의 Bind 값이 다시 Plan 생성에 사용될 수 있습니다.
05Histogram이 Bind Cardinality 추정에 주는 도움과 ACS와의 관계를 설명하시오.
Histogram과 ACS
- Histogram은 인기값과 희소값의 빈도 차이를 표현해 Bind Peeking 시 값별 Selectivity 추정에 도움을 줍니다.
- Histogram이 있어도 하나의 Plan이 모든 값에 적합해지는 것은 아닙니다.
- ACS는 실제 실행 결과를 관찰하여 선택도 범위별 여러 Plan이 필요한지를 판단합니다.
- Histogram은 Bind-Sensitive의 유일한 필수 조건으로 보지 않습니다.
06Bind-Sensitive Cursor가 되는 기본 조건과 Bind-Aware Cursor와의 차이를 설명하시오.
Bind-Sensitive와 Bind-Aware
- Optimizer가 Bind를 Peeking해 Cardinality를 계산하고 Bind가 등치·범위 Predicate에 사용되는 등 내부 조건을 만족하면 Bind-Sensitive 후보가 될 수 있습니다.
- Bind-Sensitive는 값별 실행 특성을 관찰하는 상태입니다.
- Bind-Aware는 관찰 결과 값별 Plan 차이가 중요하다고 판단되어 선택도 범위별 Child Plan을 사용할 수 있는 상태입니다.
07Bind-Aware Cursor가 새 Bind 값을 기존 Child와 연결하거나 새 Plan을 만드는 흐름을 설명하시오.
새 Bind 값의 Child 선택
- Bind-Aware 상태에서 새 Bind 값의 Selectivity를 계산합니다.
- 기존 Child가 관리하는 Low·High 선택도 범위와 비교합니다.
- 범위가 맞으면 기존 Child Plan을 재사용합니다.
- 적합한 범위가 없으면 Hard Parse 후 새 Child와 Plan을 만들 수 있습니다.
- 값 수만큼 무조건 새 Child를 만들지는 않습니다.
08Cursor Merging의 발생 조건과 목적을 설명하시오.
Cursor Merging
- 새 Bind 범위를 위해 생성한 Child Plan이 기존 Child Plan과 같을 때 발생할 수 있습니다.
- Oracle은 두 선택도 범위를 하나의 Child에 합치고 중복 Child를 Not Shareable 처리할 수 있습니다.
- 목적은 Library Cache 공간과 불필요한 Child Cursor를 줄이고 기존 Plan의 재사용 범위를 넓히는 것입니다.
09Adaptive Cursor Sharing과 CURSORSHARING=FORCE의 목적·대상·한계를 비교하시오.
ACS와 CURSOR_SHARING=FORCE
- ACS는 Bind SQL에서 Bind 선택도에 적합한 Child Plan을 선택하는 기능입니다.
CURSOR_SHARING=FORCE는 Literal SQL을 System-Generated Bind 형태로 치환하여 Parent Cursor 공유 가능성을 높이는 Parameter입니다.- 두 기능은 독립적이며 ACS는 사용자 Bind와 FORCE가 만든 System Bind 모두에 적용될 수 있습니다.
- FORCE는 Parse Call 제거, SQL Injection 방어, 값별 최적 Plan을 자동 보장하지 않으며 영구 설계의 대체 수단으로 권장되지 않습니다.
10V$SQL, V$SQLCSSELECTIVITY, V$SQLCSSTATISTICS, V$SQLCSHISTOGRAM을 이용한 ACS 진단 절차를 설명하시오.
ACS 진단 View
- V$SQL에서 CHILD_NUMBER, PLAN_HASH_VALUE, EXECUTIONS, IS_BIND_SENSITIVE, IS_BIND_AWARE, IS_SHAREABLE와 실행당 Buffer·CPU·Elapsed를 비교합니다.
- V$SQL_CS_SELECTIVITY에서 Child별 Predicate 선택도 Low·High 범위를 확인합니다.
- V$SQL_CS_STATISTICS에서 Bind-Aware 판단에 사용된 Row·Buffer Gets·CPU 표본을 확인합니다.
- V$SQL_CS_HISTOGRAM에서 ACS 모니터링 실행 횟수의 Bucket 분포를 확인합니다.
- Child가 여러 개라는 이유만으로 ACS라고 단정하지 않고 V$SQL_SHARED_CURSOR로 Bind Metadata·환경 차이를 분리합니다.