You are on page 1of 51

Using Adaptive Cursor Sharing (ACS) to produce multiple Optimal Plans

Carlos Sierra

Carlos Sierra

!! Enkitec Consultant !! Oracle Performance !! SQL Tuning !! PL/SQL

Adaptive Cursor Sharing (ACS)


!! Motivation !! Mechanics !! Test Case !! Demo !! Remarks

ACS Motivation

SQL Processing
Hard parsing is expensive!
!! Hard parse side effects
! CPU consumption ! Latch contention

!! Excessive hard parsing


! Affects concurrency ! Restricts scalability

!! Mitigating hard parsing


! Cursor sharing

Implementing Cursor Sharing


Replacing literals with bind variables

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

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

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

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

ACS Mechanics

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

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

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

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

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

ACS Test Case

Our Query with Literals


Guesstimate execution plan then verify it with demo 0

18

Possible Access Paths?

19

Optimal Execution Plan

20

Our Query with Bind Variables


How many optimal execution plans can you foresee?

21

Multiple Optimal Plans for one Query


Guesstimate optimal plan (access paths) for each query

Query q1 q2 q3 q4 q5

:b1 9 5 2 9 2

:b2 33 32 999 999 33

AP1 N1

AP2 N2

22

Multiple Optimal Plans for one Query


Guesstimate optimal plan (access paths) for each query

Query q1 q2 q3 q4 q5

:b1 9 5 2 9 2

:b2 33 32 999 999 33

AP1 N1 N1 FTS N1 FTS

AP2 N2 N2 FTS FTS N2

23

Multiple Optimal Plans for one Query


Execute demos 1-5 and verify access paths

Query q1 q2 q3 q4 q5

:b1 9 5 2 9 2

:b2 33 32 999 999 33

AP1 N1 N1 FTS N1 FTS

AP2 N2 N2 FTS FTS N2

24

Bind Sensitive: Rows Processed


Monitor v$sql_cs_statistics.rows_processed
!! Data volume manipulated
! Fuzzy representation ! S: few rows ! M: thousands or rows ! L: millions of rows

Query q1 q2 q3 q4 q5

:b1 9 5 2 9 2

:b2 33 32 999 33

Optimal N1/N2 N1/N2 N1/FTS FTS/N2

Rows Processed 37,382 2 8,021,324 6,233,815 1,825,131


25

!! v$sql_cs_histogram
! Bucket(0): S ! Bucket(1): M ! Bucket(2): L

999 FTS/FTS

ACS Demo

Demo 6: When Cursor becomes Bind Aware?


Obtain rows processed from demo 1-5 then guesstimate aware flag
Rows Processed 37,382 2 8,021,324 6,233,815 1,825,131

Query q1 q2 q3 q4 q5

:b1 9 5 2 9 2

:b2 33 32 999 33

Optimal N1/N2 N1/N2 N1/FTS FTS/N2

Bucket

Aware

Child

Actual

999 FTS/FTS

27

Demo 6: When Cursor becomes Bind Aware?


Obtain rows processed from demo 1-5 then guesstimate aware flag
Rows Processed 37,382 2 8,021,324 6,233,815 1,825,131

Query q1 q2 q3 q4 q5

:b1 9 5 2 9 2

:b2 33 32 999 33

Optimal N1/N2 N1/N2 N1/FTS FTS/N2

Bucket 1 0 2 2 2

Aware

Child

Actual

999 FTS/FTS

28

Demo 6: When Cursor becomes Bind Aware?


Obtain rows processed from demo 1-5 then guesstimate aware flag
Rows Processed 37,382 2 8,021,324 6,233,815 1,825,131

Query q1 q2 q3 q4 q5

:b1 9 5 2 9 2

:b2 33 32 999 33

Optimal N1/N2 N1/N2 N1/FTS FTS/N2

Bucket 1 0 2 2 2

Aware N N Y Y Y

Child

Actual

999 FTS/FTS

29

Demo 6: When Cursor becomes Bind Aware?


Obtain rows processed from demo 1-5 then guesstimate aware flag
Rows Processed 37,382 2 8,021,324 6,233,815 1,825,131

Query q1 q2 q3 q4 q5

:b1 9 5 2 9 2

:b2 33 32 999 33

Optimal N1/N2 N1/N2 N1/FTS FTS/N2

Bucket 1 0 2 2 2

Aware N N Y Y Y

Child 0 0 1 2 3

Actual N1/N2 N1/N2 FTS/FTS N1/FTS FTS/N2

999 FTS/FTS

30

Demo 6: When Cursor becomes Bind Aware?


Obtain rows processed from demo 1-5 then guesstimate aware flag
Rows Processed 37,382 2 8,021,324 6,233,815 1,825,131

Query q1 q2 q3 q4 q5

:b1 9 5 2 9 2

:b2 33 32 999 33

Optimal N1/N2 N1/N2 N1/FTS FTS/N2

Bucket 1 0 2 2 2

Aware N N Y Y Y

Child 0 0 1 2 3

Actual N1/N2 N1/N2 FTS/FTS N1/FTS FTS/N2

999 FTS/FTS

31

Demo 7: When Cursor becomes Bind Aware?


Compute bucket and guesstimate aware flag and actual plan
Rows Processed 1,825,131 6,233,815 8,021,324 2 37,382

Query q5 q4 q3 q2 q1

:b1 2 9 2 5 9

:b2 33 999 32 33

Optimal FTS/N2 N1/FTS N1/N2 N1/N2

Bucket

Aware

Child

Actual

999 FTS/FTS

32

Demo 7: When Cursor becomes Bind Aware?


Compute bucket and guesstimate aware flag and actual plan
Rows Processed 1,825,131 6,233,815 8,021,324 2 37,382

Query q5 q4 q3 q2 q1

:b1 2 9 2 5 9

:b2 33 999 32 33

Optimal FTS/N2 N1/FTS N1/N2 N1/N2

Bucket 2 2 2 0 1

Aware

Child

Actual

999 FTS/FTS

33

Demo 7: When Cursor becomes Bind Aware?


Compute bucket and guesstimate aware flag and actual plan
Rows Processed 1,825,131 6,233,815 8,021,324 2 37,382

Query q5 q4 q3 q2 q1

:b1 2 9 2 5 9

:b2 33 999 32 33

Optimal FTS/N2 N1/FTS N1/N2 N1/N2

Bucket 2 2 2 0 1

Aware N N N N Y

Child

Actual

999 FTS/FTS

34

Demo 7: When Cursor becomes Bind Aware?


Compute bucket and guesstimate aware flag and actual plan
Rows Processed 1,825,131 6,233,815 8,021,324 2 37,382

Query q5 q4 q3 q2 q1

:b1 2 9 2 5 9

:b2 33 999 32 33

Optimal FTS/N2 N1/FTS N1/N2 N1/N2

Bucket 2 2 2 0 1

Aware N N N N Y

Child 0 0 0 0 1

Actual FTS/N2 FTS/N2 FTS/N2 FTS/N2 N1/N2

999 FTS/FTS

35

Demo 7: When Cursor becomes Bind Aware?


Compute bucket and guesstimate aware flag and actual plan
Rows Processed 1,825,131 6,233,815 8,021,324 2 37,382

Query q5 q4 q3 q2 q1

:b1 2 9 2 5 9

:b2 33 999 32 33

Optimal FTS/N2 N1/FTS N1/N2 N1/N2

Bucket 2 2 2 0 1

Aware N N N N Y

Child 0 0 0 0 1

Actual FTS/N2 FTS/N2 FTS/N2 FTS/N2 N1/N2

999 FTS/FTS

36

Demo 8: When Cursor becomes Bind Aware?


Guesstimate aware flag and actual plan
Rows Processed 1,825,131 6,233,815 8,021,324 37,382 2

Query q5 q4 q3 q1 q2

:b1 2 9 2 9 5

:b2 33 999 33 32

Optimal FTS/N2 N1/FTS N1/N2 N1/N2

Bucket 2 2 2 1 0

Aware

Child

Actual

999 FTS/FTS

37

Demo 8: When Cursor becomes Bind Aware?


Guesstimate aware flag and actual plan
Rows Processed 1,825,131 6,233,815 8,021,324 37,382 2

Query q5 q4 q3 q1 q2

:b1 2 9 2 9 5

:b2 33 999 33 32

Optimal FTS/N2 N1/FTS N1/N2 N1/N2

Bucket 2 2 2 1 0

Aware N N N N N

Child

Actual

999 FTS/FTS

38

Demo 8: When Cursor becomes Bind Aware?


Guesstimate aware flag and actual plan
Rows Processed 1,825,131 6,233,815 8,021,324 37,382 2

Query q5 q4 q3 q1 q2

:b1 2 9 2 9 5

:b2 33 999 33 32

Optimal FTS/N2 N1/FTS N1/N2 N1/N2

Bucket 2 2 2 1 0

Aware N N N N N

Child 0 0 0 0 0

Actual FTS/N2 FTS/N2 FTS/N2 FTS/N2 FTS/N2

999 FTS/FTS

39

Demo 8: When Cursor becomes Bind Aware?


Guesstimate aware flag and actual plan
Rows Processed 1,825,131 6,233,815 8,021,324 37,382 2

Query q5 q4 q3 q1 q2

:b1 2 9 2 9 5

:b2 33 999 33 32

Optimal FTS/N2 N1/FTS N1/N2 N1/N2

Bucket 2 2 2 1 0

Aware N N N N N

Child 0 0 0 0 0

Actual FTS/N2 FTS/N2 FTS/N2 FTS/N2 FTS/N2

999 FTS/FTS

40

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

Closing Remarks

Understanding Selectivity Profile


From demo 6

Query q3 q4 q5

:b1 2 9 2

:b2 999 999 33

Child 1 2 3
43

Understanding Selectivity Profile


From demo 6

Query q3 q4 q5

:b1 2 9 2

:b2 999 999 33

Child 1 2 3
44

Understanding Selectivity Profile


From demo 6

Query q3 q4 q5

:b1 2 9 2

:b2 999 999 33

Child 1 2 3
45

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

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

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

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

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

You might also like