Hi Tom,
The link below talks about "Adaptive Cursors". I ran a simple test below and it did not seem to "take effect". Is there something I am missing? Is there a way to force this? Both is_bind_sensitive and is_bind_aware are "N" for my example below.
http://www.oracle.com/technology/pub/articles/oracle-database-11g-top-features/11g-sqlplanmanagement.html Thanks in Advance !!!
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Solaris: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
-- create simple 100,000 row table with 3 columns
CREATE TABLE tab_a AS
SELECT level pk_col, 0 col_1, rpad(' ', 100) col_2 FROM dual CONNECT BY level < 100001;
CREATE UNIQUE INDEX pk_tab_a ON tab_a(pk_col);
-- all the values for col_1 are 0 except change the last one (row 100,000)
update tab_a set col_1 = pk_col where pk_col = 100000;
commit;
CREATE INDEX idx_col_1 ON tab_a(col_1);
-- show the plan for the when we select 99,999 rows where col_1 is 0
explain plan for select count(*) from tab_a where col_1 = 0;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 1 | 13 | 46 (9)|
| 1 | SORT AGGREGATE | | 1 | 13 | |
| 2 | INDEX FAST FULL SCAN| IDX_COL_1 | 93681 | 1189K| 46 (9)|
-- show the plan for the when we select 1 row where col_1 is 100000
explain plan for select count(*) from tab_a where col_1 = 100000;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 1 | 13 | 1 (0)|
| 1 | SORT AGGREGATE | | 1 | 13 | |
| 2 | INDEX RANGE SCAN| IDX_COL_1 | 1 | 13 | 1 (0)|
-- run a anonymous block using binds showing only the first call is "peeked"
declare
l_col_1 tab_a.col_1%type;
l_cnt number;
begin
-- peek "sel_0_first" with for select 99,999 rows where col_1 is 0
l_col_1 := 0;
select count(*) sel_0_first into l_cnt from tab_a where col_1 = l_col_1;
-- peek "sel_100000_first" with for select 1 row where col_1 is 100000
l_col_1 := 100000;
select count(*) sel_100000_first into l_cnt from tab_a where col_1 = l_col_1;
-- now run the EXACT same 2 statements again - this time switch the values passed in
l_col_1 := 100000;
select count(*) sel_0_first into l_cnt from tab_a where col_1 = l_col_1;
l_col_1 := 0;
select count(*) sel_100000_first into l_cnt from tab_a where col_1 = l_col_1;
end;
-- check the work done from the SGA
-- Each statement "sel_0_first" and "sel_100000_first" was executed 2 times except the first peek value was opposite
SELECT sql_id, child_number, executions, cpu_time, elapsed_time, sql_text FROM v$sql WHERE sql_text LIKE 'SELECT COUNT(*) SEL_%';
SQL_ID CHILD_NUMBER EXECUTIONS CPU_TIME ELAPSED_TIME SQL_TEXT
1bs39xs4bqhbz 0 2 150,000 153,176 SELECT COUNT(*) SEL_0_FIRST FROM TAB_A WHERE COL_1 = :B1
6c185q85674h6 0 2 80,000 77,483 SELECT COUNT(*) SEL_100000_FIRST FROM TAB_A WHERE COL_1 = :B1
-- verify the plan from the SGA for peek where col_1 is 0 first
select * FROM TABLE(dbms_xplan.display_cursor('1bs39xs4bqhbz', 0));
PLAN_TABLE_OUTPUT
SQL_ID 1bs39xs4bqhbz, child number 0
SELECT COUNT(*) SEL_0_FIRST FROM TAB_A WHERE COL_1 = :B1
Plan hash value: 1447923
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | 46 (100)| |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX FAST FULL SCAN| IDX_COL_1 | 93681 | 1189K| 46 (9)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter("COL_1"=:B1)
-- verify the plan from the SGA for peek where col_1 is 100000 first
select * FROM TABLE(dbms_xplan.display_cursor('6c185q85674h6', 0));
PLAN_TABLE_OUTPUT
SQL_ID 6c185q85674h6, child number 0
SELECT COUNT(*) SEL_100000_FIRST FROM TAB_A WHERE COL_1 = :B1
Plan hash value: 1735350713
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | | | 1 (100)| |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX RANGE SCAN| IDX_COL_1 | 1 | 13 | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("COL_1"=:B1)