The document discusses Adaptive Cursor Sharing (ACS) in Oracle Database 11g, which allows a query with bind variables to have multiple optimal execution plans generated based on the values that are bound to the variables, in order to avoid hard parsing and improve performance. ACS monitors the amount of data accessed by a query and will generate multiple plans if the data volume varies significantly. It works by evaluating the selectivity of predicates at parse time and selecting a plan that matches the selectivity profile.
7. Before Bind Peeking
Before 9i CBO was blind to values passed
§ Predicate
– WHERE channel_id = :b1
§ Unknowns
– Is :b1 between low and high values of channel_id?
– Is :b1 a popular value of channel_id?
– Are there any rows with value :b1 for channel_id?
§ Penalty
– Possible suboptimal plans
7
8. With Bind Peeking
9i offers a partial solution
§ Predicate
– WHERE channel_id = :b1
§ Plan is determined by peeked values
– EXEC :b1 := 9;
§ Optimal plan for 1st execution
– CBO can use low/high and histograms on channel_id
§ Penalty
– Possible suboptimal plans for subsequent executions on skewed data
8
9. Real-life Problem with Bind Peeking
People Soft Payroll Application
§ WHERE employee BETWEEN :b1 AND :b2
§ Payroll for one employee
– :b1 = 123456
– :b2 = 123456
§ Payroll for one company
– :b1 = 000001
– :b2 = 999999
§ Doing payroll for an employee first then entire company
9
10. With Adaptive Cursor Sharing
11g improves cursor sharing
§ Some queries are ACS candidates
§ Sophisticated non-persistent mechanism
§ Selectivity of predicates determine plan
§ Multiple optimal plans for a query!
– If ACS is successfully applied
§ Penalty
– Marginal increase in CPU and memory overhead
10
12. ACS high-level Overview
High level overview
§ If SQL with binds meets some requirements
– Flag cursor as bind sensitive
– Start monitoring data volume manipulated by cursor
§ If bind sensitive and data volume manipulated by cursor varies
significantly
– Flag cursor as bind aware
– Start generating multiple optimal plans for this query on next hard parse
§ If bind aware then use selectivity of predicates to decide on plan
12
13. Bind Sensitive
Minimum requirements
§ SQL has explicit binds
– Or literals and cursor_sharing is “force”
§ Predicate: column + operand + bind_variable
– Equality operand “=“ and histogram on column
§ Ex: channel_id = :b1
– Non-equality operand (range) regardless of histogram on column
§ “>”, “>=“, “<“, ‘<=“, BETWEEN, LIKE
13
14. Bind Aware
How to become bind aware?
§ Significant changes in data volume manipulated by cursor
– A few rows versus a few thousands of rows
– A few thousands of rows versus a few millions of rows
§ Specifying /*+ BIND_AWARE */ CBO Hint
– Bypasses the monitoring phase on data volume
14
15. Plan Selection
Based on selectivity profile of predicates
§ Evaluate selectivity of predicates at soft parse
§ Compare to a non-persistent selectivity profile
§ If within ranges of a known profile then select associated plan
§ Else hard parse
– Compute and execute newly generated plan
– Create selectivity profile for new plan or update profile of existing plan
§ If ranges on selectivity profiles overlap then merge profiles
15
16. V$ dynamic views for ACS
ACS non-persistent performance views
§ V$SQL
– Shareable, bind sensitive and bind aware flags
§ V$SQL_CS_STATISTICS
– Data volume manipulated (rows processed)
§ V$SQL_CS_HISTOGRAM
– Record keeping of data volume per execution (small, medium, large)
§ V$SQL_CS_SELECTIVITY
– Predicates selectivity profiles
16
29. Demo 6: When Cursor becomes Bind Aware?
Obtain rows processed from demo 1-5 then guesstimate aware flag
Query
:b1
:b2
Optimal
q1
9
33
N1/N2
q2
5
32
N1/N2
q3
2
q4
q5
Rows
Processed
Bucket
Aware
37,382
1
N
2
0
N
999 FTS/FTS
8,021,324
2
Y
9
999
N1/FTS
6,233,815
2
Y
2
33
FTS/N2
1,825,131
2
Child
Actual
Y
29
30. Demo 6: When Cursor becomes Bind Aware?
Obtain rows processed from demo 1-5 then guesstimate aware flag
Query
:b1
:b2
Optimal
q1
9
33
N1/N2
q2
5
32
N1/N2
q3
2
q4
q5
Rows
Processed
Bucket
Aware
Child
Actual
37,382
1
N
0
N1/N2
2
0
N
0
N1/N2
999 FTS/FTS
8,021,324
2
Y
1
FTS/FTS
9
999
N1/FTS
6,233,815
2
Y
2
N1/FTS
2
33
FTS/N2
1,825,131
2
Y
3
FTS/N2
30
31. Demo 6: When Cursor becomes Bind Aware?
Obtain rows processed from demo 1-5 then guesstimate aware flag
Query
:b1
:b2
Optimal
q1
9
33
N1/N2
q2
5
32
N1/N2
q3
2
q4
q5
Rows
Processed
Bucket
Aware
Child
Actual
37,382
1
N
0
N1/N2
2
0
N
0
N1/N2
999 FTS/FTS
8,021,324
2
Y
1
FTS/FTS
9
999
N1/FTS
6,233,815
2
Y
2
N1/FTS
2
33
FTS/N2
1,825,131
2
Y
3
FTS/N2
31
32. Demo 7: When Cursor becomes Bind Aware?
Compute bucket and guesstimate aware flag and actual plan
Rows
Processed
Query
:b1
:b2
Optimal
Bucket
q5
2
33
FTS/N2
1,825,131
q4
9
999
N1/FTS
6,233,815
q3
2
999 FTS/FTS
q2
5
32
N1/N2
2
q1
9
33
N1/N2
Aware
Child
Actual
37,382
8,021,324
32
33. Demo 7: When Cursor becomes Bind Aware?
Compute bucket and guesstimate aware flag and actual plan
Rows
Processed
Query
:b1
:b2
Optimal
Bucket
q5
2
33
FTS/N2
1,825,131
2
q4
9
999
N1/FTS
6,233,815
2
q3
2
999 FTS/FTS
8,021,324
2
q2
5
32
N1/N2
2
0
q1
9
33
N1/N2
37,382
Aware
Child
Actual
1
33
34. Demo 7: When Cursor becomes Bind Aware?
Compute bucket and guesstimate aware flag and actual plan
Query
:b1
:b2
Optimal
q5
2
33
FTS/N2
q4
9
999
N1/FTS
q3
2
999 FTS/FTS
q2
5
32
q1
9
33
Rows
Processed
Bucket
Aware
1,825,131
2
N
6,233,815
2
N
8,021,324
2
N
N1/N2
2
0
N
N1/N2
37,382
1
Child
Actual
Y
34
35. Demo 7: When Cursor becomes Bind Aware?
Compute bucket and guesstimate aware flag and actual plan
Query
:b1
:b2
Optimal
q5
2
33
FTS/N2
q4
9
999
N1/FTS
q3
2
999 FTS/FTS
q2
5
32
q1
9
33
Rows
Processed
Bucket
Aware
Child
Actual
1,825,131
2
N
0
FTS/N2
6,233,815
2
N
0
FTS/N2
8,021,324
2
N
0
FTS/N2
N1/N2
2
0
N
0
FTS/N2
N1/N2
37,382
1
Y
1
N1/N2
35
36. Demo 7: When Cursor becomes Bind Aware?
Compute bucket and guesstimate aware flag and actual plan
Query
:b1
:b2
Optimal
q5
2
33
FTS/N2
q4
9
999
N1/FTS
q3
2
999 FTS/FTS
q2
5
32
q1
9
33
Rows
Processed
Bucket
Aware
Child
Actual
1,825,131
2
N
0
FTS/N2
6,233,815
2
N
0
FTS/N2
8,021,324
2
N
0
FTS/N2
N1/N2
2
0
N
0
FTS/N2
N1/N2
37,382
1
Y
1
N1/N2
36
37. Demo 8: When Cursor becomes Bind Aware?
Guesstimate aware flag and actual plan
Rows
Processed
Query
:b1
:b2
Optimal
Bucket
q5
2
33
FTS/N2
1,825,131
2
q4
9
999
N1/FTS
6,233,815
2
q3
2
999 FTS/FTS
8,021,324
2
q1
9
33
N1/N2
37,382
1
q2
5
32
N1/N2
2
Aware
Child
Actual
0
37
38. Demo 8: When Cursor becomes Bind Aware?
Guesstimate aware flag and actual plan
Query
:b1
:b2
Optimal
q5
2
33
FTS/N2
q4
9
999
N1/FTS
q3
2
999 FTS/FTS
q1
9
33
q2
5
32
Rows
Processed
Bucket
Aware
1,825,131
2
N
6,233,815
2
N
8,021,324
2
N
N1/N2
37,382
1
N
N1/N2
2
0
Child
Actual
N
38
39. Demo 8: When Cursor becomes Bind Aware?
Guesstimate aware flag and actual plan
Query
:b1
:b2
Optimal
q5
2
33
FTS/N2
q4
9
999
N1/FTS
q3
2
999 FTS/FTS
q1
9
33
q2
5
32
Rows
Processed
Bucket
Aware
Child
Actual
1,825,131
2
N
0
FTS/N2
6,233,815
2
N
0
FTS/N2
8,021,324
2
N
0
FTS/N2
N1/N2
37,382
1
N
0
FTS/N2
N1/N2
2
0
N
0
FTS/N2
39
40. Demo 8: When Cursor becomes Bind Aware?
Guesstimate aware flag and actual plan
Query
:b1
:b2
Optimal
q5
2
33
FTS/N2
q4
9
999
N1/FTS
q3
2
999 FTS/FTS
q1
9
33
q2
5
32
Rows
Processed
Bucket
Aware
Child
Actual
1,825,131
2
N
0
FTS/N2
6,233,815
2
N
0
FTS/N2
8,021,324
2
N
0
FTS/N2
N1/N2
37,382
1
N
0
FTS/N2
N1/N2
2
0
N
0
FTS/N2
40
41. Real-life Problem with ACS
People Soft Payroll Application
§ WHERE employee BETWEEN :b1 AND :b2
§ Payroll for one employee
– :b1 = 123456
– :b2 = 123456
§ Payroll for one company
– :b1 = 000001
– :b2 = 999999
§ Doing payroll for a few employees first then entire company
41
46. Remarks on Bind Sensitivity
Based on experimental observation
§ Monitor V$SQL_CS_STATISTICS.rows_processed
– If small number of rows then
§ V$SQL_CS_HISTOGRAM.bucket_id(0)++
– If medium number of rows then
§ V$SQL_CS_HISTOGRAM.bucket_id(1)++
– If large number of rows then
§ V$SQL_CS_HISTOGRAM.bucket_id(2)++
46
47. Remarks on Bind Aware
Based on experimental observation
§ Some cases where cursor may become bind aware
– bucket_id(0) = bucket_id(1) > 0
– bucket_id(1) = bucket_id(2) > 0
– bucket_id(0) > 0 and bucket_id(2) > 0
§ Or use /*+ BIND_AWARE */ CBO Hint
– What if we cannot modify code?
47
48. Conclusions
ACS can produce multiple optimal plans for one query
§ ACS only applies to a subset of queries with binds
§ ACS requires a ramp-up process (few executions)
§ In some cases cursor may fail to become bind aware
§ To force a cursor become bind aware use CBO Hint
§ ACS is not persistent
§ ACS works well with SQL Plan Management
48
49. Give Away
Script sqlt/utl/coe_gen_sql_patch.sql (MOS 215187.1)
§ Creates a SQL Patch for one SQL_ID
§ Turns “on” EVENT 10053 for SQL_ID
§ Hints on SQL Patch
– GATHER_PLAN_STATISTICS
– MONITOR
– BIND_AWARE
§ Consider using and customizing this free script
49
50. References and Contact Info
Oracle Optimizer Blog
§ https://blogs.oracle.com/optimizer/
– Insight into the workings of the Optimizer
§ carlos.sierra@enkitec.com
§ http://carlos-sierra.net
§ @csierra_usa
50