Post on 15-Jan-2017
transcript
28/11/15 Mohamed Houri www.hourim.wordpress.com1
Adaptive Cursor SharingShort answer to sharing cursors and optimizing SQL
Mohamed Houri
www.hourim.wordpress.com
Mohamed Houri
www.hourim.wordpress.com
28/11/15 Mohamed Houri www.hourim.wordpress.com2
Agenda
Set the scene Expose the performance problem caused by sharing cursors Literal, bind variable, bind variable peeking and hard parsing Introduce Adaptive Cursor Sharing feature
Adaptive Cursor SharingExplain the cursor bind sensitive propertyExplain the cursor bind aware propertyShow a simple practical ACS exampleExplain the ACS monitoring v$sql viewsUncover the bind aware secret sauceShow how ACS can introduce a serious perfomance issue
Conclusion
28/11/15 Mohamed Houri www.hourim.wordpress.com3
WHAT IS THE PROBLEM?
PART 0
Set the scene
28/11/15 Mohamed Houri www.hourim.wordpress.com4
Syntactic checkSyntax, keywords
Semantic checkAccess, right, exist Store parent cursor in
v$sql(SGA)
Logical Optimization
Physical Optimization
Store child cursor in v$sql(SGA)
Parent cursor?
Child cursor?
Execute SQL
No
No
Yes
Yes
Set the scene
Ha
rd p
arse
So
ft par se
28/11/15 Mohamed Houri www.hourim.wordpress.com5
Using Literal variable➔ hard parsing for each execution➔ traumatizes the SGA➔ burns a lot CPU
Set the scene
Using bind variables➔ avoids hard parsing➔ makes the SGA attractive➔ uses less resource - CPU
generates “always“ an optimal plan
sharing plan is not always optimal
28/11/15 Mohamed Houri www.hourim.wordpress.com6
How to have best-of-both-world?
Set the scene
➔ Attractive SGA + less CPU consumption➔ Optimal execution plan for each execution
Adaptive Cursor Sharing-ACS
28/11/15 Mohamed Houri www.hourim.wordpress.com7
ACS - triggering diagram
Invesigate this property
28/11/15 Mohamed Houri www.hourim.wordpress.com8
WHEN A CURSOR IS BIND SENSITIVE?
PART I
ACS
28/11/15 Mohamed Houri www.hourim.wordpress.com9
SQL> desc V$SQL
Name Null? Type ------------------------------- -------- ------------- 1 SQL_TEXT VARCHAR2(1000) 2 SQL_FULLTEXT CLOB 3 SQL_ID VARCHAR2(13) 45 CHILD_NUMBER NUMBER 63 IS_OBSOLETE VARCHAR2(1) 64 IS_BIND_SENSITIVE VARCHAR2(1) 65 IS_BIND_AWARE VARCHAR2(1) 66 IS_SHAREABLE VARCHAR2(1)
ACS - v$sql
28/11/15 Mohamed Houri www.hourim.wordpress.com10
ACS – modelSQL> create table t_acs(n1 number, n2 number);SQL> BEGIN for j in 1..1200150 loop if j = 1 then insert into t_acs values (j, 1); elsif j>1 and j<=101 then insert into t_acs values(j, 100); elsif j>101 and j<=1101 then insert into t_acs values (j, 1000); elsif j>10001 and j<= 110001 then insert into t_acs values(j,10000); else insert into t_acs values(j, 1000000); end if; end loop; commit;END;
Inflexion point
Inflexion point
28/11/15 Mohamed Houri www.hourim.wordpress.com11
ACS – modelSQL> create index t_acs_i1 on t_acs(n2);
SQL> BEGIN dbms_stats.gather_table_stats (user ,'t_acs' ,method_opt => 'for all columns size 1' ,cascade => true ,estimate_percent => dbms_stats.auto_sample_size );END;/
–- declare and affect a value to a bind variable–- and run a query with range predicate
SQL> var ln2 number;SQL> exec :ln2 := 100;
Without histogram
28/11/15 Mohamed Houri www.hourim.wordpress.com12
ACS – bind sensitive : range predicateSQL> select count(1) from t_acs where n2 <= :ln2;
SQL> select sql_id ,child_number ,is_bind_sensitive from v$sql where sql_id = 'ct0yv82p15jdw';
SQL_ID CHILD_NUMBER IS_BIND_SENSITIVE------------- ------------ -----------------ct0yv82p15jdw 0 Y
range predicate
cursor is bind sensitive
28/11/15 Mohamed Houri www.hourim.wordpress.com13
ACS – bind sensitive : equality predicate with histogramSQL> BEGIN dbms_stats.gather_table_stats (user,'t_acs' ,method_opt => 'for all columns size auto' ,cascade => true ,estimate_percent => dbms_stats.auto_sample_size); END;/
SQL> SELECT column_name, histogram FROM user_tab_col_statistics WHERE table_name = 'T_ACS' AND column_name = 'N2';
COLUMN_NAME HISTOGRAM----------------- -----------N2 FREQUENCY
with histogram
with histogram
28/11/15 Mohamed Houri www.hourim.wordpress.com14
ACS – bind sensitive : equality predicate with histogram
SQL> select count(1) from t_acs where n2 = :ln2;
SQL> select sql_id ,child_number ,is_bind_sensitive from v$sql where sql_id = 'f2pmwazy1rnfd';
SQL_ID CHILD_NUMBER IS_BIND_SENSITIVE ------------- ------------ –----------------- f2pmwazy1rnfd 0 Y
equality predicate with histogram
cursor is bind sensitive
28/11/15 Mohamed Houri www.hourim.wordpress.com15
ACS – bind sensitive : partition key
SQL> create table t_acs_part(n1 number, n2 number)partition by range (n2)( partition p1 values less than (100) ,partition p2 values less than (1000) ,partition p3 values less than (10000) ,partition p4 values less than (100000) ,partition p5 values less than (1000000) ,partition p6 values less than (10000000));
SQL> –- insert data and gather stats without histogramSQL> select column_name, histogram FROM user_tab_col_statistics where table_name = 'T_ACS_PART' AND column_name = 'N2';
COLUMN_NAM HISTOGRAM---------- ---------N2 NONE
28/11/15 Mohamed Houri www.hourim.wordpress.com16
ACS – bind sensitive : partition key
SQL> select count(1) from t_acs where n2 = :ln2;
SQL> select sql_id ,child_number ,is_bind_sensitive from v$sql where sql_id = 'byztzuffb65n9';
SQL_ID CHILD_NUMBER IS_BIND_SENSITIVE ------------- ------------ –---------------- byztzuffb65n9 0 Y
partition key
cursor is bind sensitive
28/11/15 Mohamed Houri www.hourim.wordpress.com17
ACS – bind sensitive : summary
range predicate (with simple statistics)
SQL> select count(1) from t_acs where n2 <= :ln2;
equality predicate (with histogram)
SQL> select count(1) from t_acs where n2 = :ln2;
predicate with partition key (simple stats)
SQL> select count(1) from t_acs where n2 = :ln2;
28/11/15 Mohamed Houri www.hourim.wordpress.com18
18
PART II
ACS-simple example
A SIMPLE ACS EXAMPLE
28/11/15 Mohamed Houri www.hourim.wordpress.com19
ACS-simple example
SQL> exec :ln2 := 100
SQL> select count(1) from t_acs where n2 = :ln2;
SQL> select n2,count(1) from t_acs group by n2 order by 2;
N2 COUNT(1)---------- ---------- 1 1 100 100 1000 1000 10000 100000 1000000 1099049
index range scan
full table scan
28/11/15 Mohamed Houri www.hourim.wordpress.com20
ACS-simple example
SQL_ID f2pmwazy1rnfd, child number 0-----------------------------------------------------| Id | Operation | Name | Rows | Bytes |-----------------------------------------------------| 0 | SELECT STATEMENT | | | || 1 | SORT AGGREGATE | | 1 | 3 ||* 2 | INDEX RANGE SCAN| T_ACS_I1 | 856 | 2568 | -----------------------------------------------------
Predicate Information (identified by operation id):--------------------------------------------------- 2 - access("N2"=:LN2)
optimal plan for the first execution.Plan has been hard parsed
28/11/15 Mohamed Houri www.hourim.wordpress.com21
ACS-simple example
SQL> exec :ln2 := 1000000
–- 1st execution with bind variable value = 1000000SQL> select count(1) from t_acs where n2 = :ln2;
SQL_ID f2pmwazy1rnfd, child number 0-----------------------------------------------------| Id | Operation | Name | Rows | Bytes |-----------------------------------------------------| 0 | SELECT STATEMENT | | | || 1 | SORT AGGREGATE | | 1 | 3 ||* 2 | INDEX RANGE SCAN| T_ACS_I1 | 856 | 2568 | -----------------------------------------------------
Predicate Information (identified by operation id):--------------------------------------------------- 2 - access("N2"=:LN2)
sharing plan is bad here
28/11/15 Mohamed Houri www.hourim.wordpress.com22
ACS-simple example
SQL> exec :ln2 := 1000000
–- 2nd execution with bind variable value = 1000000SQL> select count(1) from t_acs where n2 = :ln2;
SQL_ID f2pmwazy1rnfd, child number 1-----------------------------------------------------| Id | Operation | Name | Rows | Bytes |-----------------------------------------------------| 0 | SELECT STATEMENT | | | || 1 | SORT AGGREGATE | | 1 | 3 ||* 2 | TABLE ACCESS FULL| T_ACS | 1104K| 3235K|-----------------------------------------------------
Predicate Information (identified by operation id):--------------------------------------------------- 2 – filter("N2"=:LN2) optimal plan at the second
execution
28/11/15 Mohamed Houri www.hourim.wordpress.com23
ACS-simple example
–- back to the first bind variable value 100SQL> exec :ln2 := 100
SQL> select count(1) from t_acs where n2 = :ln2;
SQL_ID f2pmwazy1rnfd, child number 2------------------------------------------------------| Id | Operation | Name | Rows | Bytes | ------------------------------------------------------| 0 | SELECT STATEMENT | | | || 1 | SORT AGGREGATE | | 1 | 3 ||* 2 | INDEX RANGE SCAN| T_ACS_I1 | 1713 | 5139 |------------------------------------------------------
Predicate Information (identified by operation id):--------------------------------------------------- 2 – access("N2"=:LN2) execution plan is now immediately
optimal
28/11/15 Mohamed Houri www.hourim.wordpress.com24
SQL> select sql_id ,child_number ,is_bind_sensitive ,is_bind_aware from v$sql where sql_id = 'f2pmwazy1rnfd';
SQL_ID CHILD_NUMBER IS_BIND_SENS IS_BIND_AWARE------------- ------------ –----------- –-------------f2pmwazy1rnfd 0 Y N → index-RS f2pmwazy1rnfd 1 Y Y → table-FSf2pmwazy1rnfd 2 Y Y → index-RS
is that cursor is now bind aware
what happens?
ACS-simple example
28/11/15 Mohamed Houri www.hourim.wordpress.com25
ACS-simple example
We have gone wrong(index range scan plan shared) during the first execution with :ln2 := 1000000
It is until the second execution with :ln2 := 1000000 that Oracle has compiled a new optimal plan (full table scan)
We have to share the “wrong” plan during a certain number of executions
This “certain number” of executions is strongly related to the number of executions done at the initial bind variable value :ln2 := 100
This execution-count relationship will be explained later
(BUCKET_ID, COUNT)
28/11/15 Mohamed Houri www.hourim.wordpress.com26
26
PART III
ACS-bind aware secret sauce
When Oracle decides that it is time to compile a new execution plan?
28/11/15 Mohamed Houri www.hourim.wordpress.com27
27
SQL> desc V$SQL_CS_STATISTICS
Name Null? Type ------------------------------- -------- -------------- 1 ADDRESS RAW(8) 2 HASH_VALUE NUMBER 3 SQL_ID VARCHAR2(13) 4 CHILD_NUMBER NUMBER 5 BIND_SET_HASH_VALUE NUMBER 6 PEEKED VARCHAR2(1) 7 EXECUTIONS NUMBER 8 ROWS_PROCESSED NUMBER 9 BUFFER_GETS NUMBER 10 CPU_TIME NUMBER 11 CON_ID NUMBER
ACS-bind aware secret sauce
Starting from 12c this view is obsolete
28/11/15 Mohamed Houri www.hourim.wordpress.com28
28
SQL> desc V$SQL_CS_HISTOGRAM
Name Null? Type ------------------------------- -------- ------------- 1 ADDRESS RAW(8) 2 HASH_VALUE NUMBER 3 SQL_ID VARCHAR2(13) 4 CHILD_NUMBER NUMBER 5 BUCKET_ID NUMBER 6 COUNT NUMBER 7 CON_ID NUMBER
ACS-bind aware secret sauce
number of executionsdone at this child_number
linked to the number ofrows processed by this child_number
28/11/15 Mohamed Houri www.hourim.wordpress.com29
29
SQL> desc V$SQL_CS_SELECTIVITY
Name Null? Type ----------------------- -------- -------------- 1 ADDRESS RAW(8) 2 HASH_VALUE NUMBER 3 SQL_ID VARCHAR2(13) 4 CHILD_NUMBER NUMBER 5 PREDICATE VARCHAR2(40) 6 RANGE_ID NUMBER 7 LOW VARCHAR2(10) 8 HIGH VARCHAR2(10) 9 CON_ID NUMBER
ACS-bind aware secret sauce
This view becomes usefulonly when cursor is
bind aware
28/11/15 Mohamed Houri www.hourim.wordpress.com30
30
ACS-bind aware secret sauce
0 <= ROWS_PROCESSED< 1,000 increments COUNT
of BUCKET_ID n° 0
1,000 <= ROWS_PROCESSED<= 1,000,000 increments COUNT
of BUCKET_ID n° 1
ROWS_PROCESSED> 1,000,000 increments COUNT
of BUCKET_ID n° 2
Inflexion point
Inflexion point
28/11/15 Mohamed Houri www.hourim.wordpress.com31
SQL> exec :ln2 := 100 –- 1st execution with this valueSQL> select count(1) from t_acs where n2 = :ln2; COUNT(1)---------- 100
ACS-bind aware secret sauce
Nbr of rows processed <1000
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 1 0 1 0 0 2 0
count(bucket_id n°0)incremented
28/11/15 Mohamed Houri www.hourim.wordpress.com32
SQL> exec :ln2 := 100 –- 2nd execution with this valueSQL> select count(1) from t_acs where n2 = :ln2; COUNT(1)---------- 100
ACS-bind aware secret sauce
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 2 0 1 0 0 2 0
count(bucket_id n°0)incremented
Nbr of rows processed <1000
28/11/15 Mohamed Houri www.hourim.wordpress.com33
SQL> exec :ln2 := 100 –- 3rd execution with this valueSQL> select count(1) from t_acs where n2 = :ln2; COUNT(1)---------- 100
ACS-bind aware secret sauce
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 3 0 1 0 0 2 0
count(bucket_id n°0)incremented
Nbr of rows processed <1000
28/11/15 Mohamed Houri www.hourim.wordpress.com34
SQL> exec :ln2 := 1000 –- 1st execution with this valueSQL> select count(1) from t_acs where n2 = :ln2; COUNT(1)------- 1000
ACS-bind aware secret sauce
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 3 0 1 1 0 2 0
count(bucket_id n°1)incremented
1000<= Nbr of rows processed <= 1e6
still sharing same plan
28/11/15 Mohamed Houri www.hourim.wordpress.com35
SQL> exec :ln2 := 1000 –-2nd execution with this valueSQL> select count(1) from t_acs where n2 = :ln2; COUNT(1)------- 1000
ACS-bind aware secret sauce
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 3 0 1 2 0 2 0
count(bucket_id n°1)incremented
1000<= Nbr of rows processed <= 1e6
still sharing same plan
28/11/15 Mohamed Houri www.hourim.wordpress.com36
SQL> exec :ln2 := 1000 –-3rd execution with this valueSQL> select count(1) from t_acs where n2 = :ln2; COUNT(1)------- 1000
ACS-bind aware secret sauce
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 3 0 1 3 0 2 0
count(bucket_id n°1)incremented
1000<= Nbr of rows processed <= 1e6
still sharing same plan
28/11/15 Mohamed Houri www.hourim.wordpress.com37
SQL> exec :ln2 := 1000 –-4th execution with this valueSQL> select count(1) from t_acs where n2 = :ln2;
ACS-bind aware secret sauce
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 1 0 0 1 1 1 1 2 0 0 0 3 0 1 3 0 2 0
count(bucket_id n°1)incremented
new compiled plan
28/11/15 Mohamed Houri www.hourim.wordpress.com38
SQL> select sql_id ,child_number ,is_bind_sensitive ,is_bind_aware from v$sql where sql_id = 'f2pmwazy1rnfd';
SQL_ID CHILD_NUMBER IS_BIND_SENS IS_BIND_AWARE------------- ------------ –----------- –-------------f2pmwazy1rnfd 0 Y N f2pmwazy1rnfd 1 Y Y
cursor n° 1 is now bind aware
ACS-bind aware secret sauce
28/11/15 Mohamed Houri www.hourim.wordpress.com39
39
ACS-bind aware secret sauce – rule n° 1 : adjacent buckets
COUNT(BUCKET_ID n° 1) = COUNT(BUCKET_ID n° 0)
OR
COUNT(BUCKET_ID n° 2) = COUNT(BUCKET_ID n° 1)
The next execution at BUCKET_ID n°1 (or n°2) will mark the cursor bind aware and a new execution plan will be compiled
28/11/15 Mohamed Houri www.hourim.wordpress.com40
SQL> exec :ln2 := 100 –- bucket_id n° 0SQL> select count(1) from t_acs where n2 = :ln2;SQL> ../.. 10 executions
ACS-bind aware secret sauce : distant bucket_id
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 10 0 1 0 0 2 0
count(bucket_id n°0)Incremented 10 times
28/11/15 Mohamed Houri www.hourim.wordpress.com41
SQL> exec :ln2 := 1000000 –- bucket_id n°2SQL> select count(1) from t_acs where n2 = :ln2; COUNT(1)---------- 1099049
ACS-bind aware secret sauce : distant bucket_id
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 10 0 1 0 0 2 1
count(bucket_id n°2)Incremented 1 time
still sharing same plan
Nbr of rows > 1e6
28/11/15 Mohamed Houri www.hourim.wordpress.com42
Question : How many executions at bucket_id n°2 we need to have before Oracle compile a new optimal plan?
ACS-bind aware secret sauce : distant bucket_id
–- run this 3 timesSQL> select count(1) from t_acs where n2 = :ln2;
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 10 0 1 0 0 2 4
count(bucket_id n°2)incremented 3 times
Answer : 4 executions
still sharing thesame plan
28/11/15 Mohamed Houri www.hourim.wordpress.com43
SQL> exec :ln2 := 1000000 –-5th execution at this valueSQL> select count(1) from t_acs where n2 = :ln2;
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 1 0 0 1 1 0 1 2 1 0 0 10 0 1 0 0 2 4
10 exec at bucket_id n°0
new compiled plan
ACS-bind aware secret sauce : distant bucket_id
4 exec at bucket_id n°2
28/11/15 Mohamed Houri www.hourim.wordpress.com44
44
4 = ceil (10/3)
The next execution at BUCKET_ID n°2 will mark the cursor bind aware and a new execution plan will be compiled
ACS-bind aware secret sauce : distant bucket_id
Applies only with distant bucket_id (0 and 2)
COUNT(BUCKET_ID n° 2) = ceil (COUNT(BUCKET_ID n° 0)/3)
28/11/15 Mohamed Houri www.hourim.wordpress.com45
ACS-bind aware secret sauce : all buckets involved
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 10 0 1 3 0 2 1
Question : How many executions at bucket_id n°2 we need to have before Oracle compiles a new optimal plan?
10 exec at bucket_id n°0
3 exec at bucket_id n°1
1 exec at bucket_id n°2
28/11/15 Mohamed Houri www.hourim.wordpress.com46
ACS-bind aware secret sauce : all buckets involved-------------------------------------------------------------------------------- File name: fv_will_cs_be_bind_aware-- Author : Mohamed Houri (Mohamed.Houri@gmail.com)-- Date : 29/08/2015-- Purpose : When supplied with 3 parameters -- pin_cnt_bucket_0 : count of bucket_id n°0-- pin_cnt_bucket_1 : count of bucket_id n°1-- pin_cnt_bucket_2 : count of bucket_id n°2 -- this function will return a status:-- 'Y' if the next execution at any bucket_id will mark the cursor bind aware -- 'N' if the next execution any bucket_id will NOT mark the cursor bind aware --------------------------------------------------------------------------------create or replace function fv_will_cs_be_bind_aware (pin_cnt_bucket_0 in number,pin_cnt_bucket_1 in number,pin_cnt_bucket_2 in number)return varchar2 is lv_will_be_bind_aware varchar2(1) := 'N'; ln_least_0_2 number := least(pin_cnt_bucket_0,pin_cnt_bucket_2); ln_great_0_2 number := greatest(pin_cnt_bucket_0,pin_cnt_bucket_2);begin if pin_cnt_bucket_0 + pin_cnt_bucket_2 > = pin_cnt_bucket_1 and ln_least_0_2 >= ceil ((ln_great_0_2-pin_cnt_bucket_1)/3)then return 'Y'; else return 'N'; end if;end fv_will_cs_be_bind_aware;
28/11/15 Mohamed Houri www.hourim.wordpress.com47
ACS-bind aware secret sauce : all buckets involved
SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 10 0 1 3 0 2 1
SQL> select fv_will_cs_be_bind_aware(10,3,1) acs from dual;
ACS----N
next execution will share the same plan
28/11/15 Mohamed Houri www.hourim.wordpress.com48
SQL> exec :ln2 := 1000000 –- 2nd execution at this valueSQL> select count(1) from t_acs where n2 = :ln2; SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 10 0 1 3 0 2 2 SQL> select fv_will_cs_be_bind_aware(10,3,2) acs from dual;
ACS----N next execution will share the same plan
ACS-bind aware secret sauce : all buckets involved
28/11/15 Mohamed Houri www.hourim.wordpress.com49
SQL> exec :ln2 := 1000000 –- 3rd execution at this valueSQL> select count(1) from t_acs where n2 = :ln2; SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 0 0 10 0 1 3 0 2 3 SQL> select fv_will_cs_be_bind_aware(10,3,3) acs from dual;
ACS----Y next execution will compile a new plan
ACS-bind aware secret sauce : all buckets involved
28/11/15 Mohamed Houri www.hourim.wordpress.com50
SQL> exec :ln2 := 1000000 –- 4th execution at this valueSQL> select count(1) from t_acs where n2 = :ln2; SQL> select child_number,bucket_id,count from v$sql_cs_histogram where sql_id = 'f2pmwazy1rnfd' ;
CHILD_NUMBER BUCKET_ID COUNT------------ ---------- ---------- 1 0 0 1 1 0 1 2 1 0 0 10 0 1 3 0 2 3
new execution plan compiled
ACS-bind aware secret sauce : all buckets involved
28/11/15 Mohamed Houri www.hourim.wordpress.com51
51
The next exection at any BUCKET will mark the cursor bind aware and a new execution plan will be
compiled
SQL> select fv_will_cs_be_bind_aware (pin_cnt_bucket_0 ,pin_cnt_bucket_1 ,pin_cnt_bucket_2 )
from dual;
Existing plan will be shared
N Y
Not extensively tested!!!
ACS-bind aware secret sauce : all buckets involved
28/11/15 Mohamed Houri www.hourim.wordpress.com52
52
ACS-bind aware secret sauce : summary
COUNT(BUCKET_ID 1) = COUNT(BUCKET_ID 0)
ADJACENT BUCKET_ID (0-1 or 1-2)
next execution will compile a new execution plan
COUNT(BUCKET_ID 2) = CEIL(COUNT(BUCKET_ID 0) /3)
next execution will compile a new execution plan
DISTANT BUCKET_ID (0-2)
selectfv_will_cs_be_bind_aware(0,1,2) from dual; → Y
next execution will compile a new execution plan
ALL BUCKET_ID involved
28/11/15 Mohamed Houri www.hourim.wordpress.com53
53
PART IV
Extended Cursor Sharing
Extended Cursor Sharing- ECS
28/11/15 Mohamed Houri www.hourim.wordpress.com54
54
Extended Cursor Sharing
Adaptive Cursor Sharing
Extended Cursor Sharing
is responsible for marking bind aware a bind sensitive cursor provided one of
the 3 rules is satisfied
is responsible for checking if an execution plan of a bind aware cursor has to be
shared or a new plan has to be compiledaccording to the bind variable selectivity
it peeks at each execution
28/11/15 Mohamed Houri www.hourim.wordpress.com55
SQL> select sql_id ,child_number ,is_bind_sensitive ,is_bind_aware from v$sql where sql_id = 'f2pmwazy1rnfd';
SQL_ID CHILD_NUMBER IS_BIND_SENS IS_BIND_AWARE------------- ------------ –----------- –-------------f2pmwazy1rnfd 0 Y N f2pmwazy1rnfd 1 Y Y
once a cursor is bind aware a row exists in v$sql_cs_selectivity
Extended Cursor Sharing
28/11/15 Mohamed Houri www.hourim.wordpress.com56
SQL> select child_number ,predicate ,low ,high From v$sql_cs_selectivity where sql_id = 'f2pmwazy1rnfd';
CHILD_NUMBER PREDICATE LOW HIGH------------ ------------- ---------- ---------- 2 =LN2 0.827448 1.011325 1 =LN2 0.000807 0.000986
Extended Cursor Sharing
for each execution bind variable selectivity ischecked: if it exists in one of the LOW-HIGH
ranges then share plan. If not then compile a newplan and insert/update a new LOW-HIGH range
this is ECS
28/11/15 Mohamed Houri www.hourim.wordpress.com57
57
PART V
Extended Cursor Sharing causing a performance issue
When ACS (in fact ECS) becomes a serious performance threat
28/11/15 Mohamed Houri www.hourim.wordpress.com58
SQL> select sql_id ,count(1) from v$sql where executions < 2 group by sql_id having count(1) > 10 order by 2 desc; SQL_ID COUNT(1)------------- ----------7zwq7z1nj7vga 44217
Extended Cursor Sharing causing a performance issue
Why this high nbr of versions?
28/11/15 Mohamed Houri www.hourim.wordpress.com59
SQL> @nonshared 7zwq7z1nj7vga
Show why existing SQL child cursors were not reused(V$SQL_SHARED_CURSOR) -----------------SQL_ID : 7zwq7z1nj7vgaADDRESS : 000000406DBB30F8CHILD_ADDRESS : 00000042CE36F7E8CHILD_NUMBER : 99BIND_EQUIV_FAILURE : YREASON :<ChildNode><ChildNumber>0</ChildNumber><ID>40</ID> <reason>Bindmismatch(33)</reason><size>2x4</size> <init_ranges_in_first_pass>0</init_ranges_in_first_pass> <selectivity>1097868685</selectivity> </ChildNode>
Extended Cursor Sharing causing a performance issue
100 exec plans (0-99)
due to bind_equivalent_failure
28/11/15 Mohamed Houri www.hourim.wordpress.com60
SQL> select count(1) from v$sql_shared_cursor Where sql_id = '7zwq7z1nj7vga'; COUNT(1)---------- 45125
SQL> select count(1) from v$sql_shared_cursor Where sql_id = '7zwq7z1nj7vga' and BIND_EQUIV_FAILURE = 'Y'; COUNT(1)---------- 45121
99% of non shared cursors are due toBIND_EQUIV_FAILURE
Extended Cursor Sharing causing a performance issue
28/11/15 Mohamed Houri www.hourim.wordpress.com61
BIND_EQUIV_FAILURE : bind value's selectivity does not match that used to optimize the existing child cursor
SQL> select count(1) from v$sql_cs_selectivity where sql_id = '7zwq7z1nj7vga'; COUNT(1)---------- 16,847,320 !!!
for each execution ECS will check this view!!!
Extended Cursor Sharing causing a performance issue
CHILD_NUMBER PREDICATE LOW HIGH------------ ------------- ---------- ---------- 2 =LN2 0.827448 1.011325
28/11/15 Mohamed Houri www.hourim.wordpress.com62
Extended Cursor Sharing causing a performance issue
Run a query using a bind aware cursor
Oracle (ECS layer code) will do behind the scene:1. peeks at the bind variable value2. runs a query against v$sql_cs_selectivity(16M of rows)3. if low < selectivity < high then share existing plan4. if selectity not found in low-high range then hard parse a new plan
If another user executes the same query:1. Oracle will try to do the above 1-4 steps2. if Oracle is still busy with above 1-4 steps then we start experiencing: a) cursor: pin S wait on X b) library cache lock
28/11/15 Mohamed Houri www.hourim.wordpress.com63
63
PART V
Adaptive-Extended Cursor Sharing
FINAL ACS-ECS DIAGRAM
https://hourim.wordpress.com/2015/08/12/adaptive-cursor-sharing-triggering-mechanism/
28/11/15 Mohamed Houri www.hourim.wordpress.com64
64
Adaptive Cursor Sharing
•Conclus ion
• Lite ra l va riables a re good for query performance• ve ry bad for resource and memory• and they produce a non sca lable applica tion
• Bind variables a re not a lways good for query performance• ve ry good for resource and memory• and they produce a sca lable applica tion
• Adaptive cursor sharing a llows query good performance• even when us ing bind variable• but be aware of the extra pars ing work it might introduce