Hi, I am struggle in finding what is wrong with the SQL patch test code, i.e., I want to demonstrate I force certain operation with SQL patch, i.e., test code
drop table pojen;
create table pojen (eid number ,ename varchar2(8));
insert into pojen select level,'PO' from dual connect by level<10000;
commit;
create index idx_poeid on pojen(eid);
exec dbms_stats.gather_table_stats(null,'POJEN');
exec dbms_shared_pool.purge('00000001BA758558,3192753866','c');
set autotrace on
select * from pojen X where eid=3;
set autotrace off
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2302899125
-------------------------------------------------------------------------------------------------
| | Id | Operation | | Name | | Rows | Bytes | Cost (%CPU)| Time | | |
-------------------------------------------------------------------------------------------------
| | 0 | SELECT STATEMENT | | | | | 1 | | 19 | | 1 (0)| 00:00:01 | |
| | 1 | TABLE ACCESS BY INDEX ROWID BATCHED| POJEN | | | 1 | | 19 | | 1 (0)| 00:00:01 | |
| |* 2 | INDEX RANGE SCAN | | IDX_POEID | | 1 | | | | 1 (0)| 00:00:01 | |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EID"=3)
select sql_id,address,hash_value,'exec dbms_shared_pool.purge('''||address||','||hash_value||''',''c'');' From v$sqlarea where sql_Text like 'select * from pojen X where eid=3';
declare
v_sql CLOB;
begin
select sql_text into v_sql from v$sqlarea where sql_id='axbznkfz4v3qa';
sys.dbms_sqldiag_internal.i_create_patch(
sql_text => v_sql,
hint_text => 'FULL(X)',
name => 'patch_po2');
end;
/
exec dbms_shared_pool.purge('00000001BA758558,3192753866','c');
-- expect full table scan but got index range
set autotrace on
select * from pojen X where eid=3;
set autotrace off
-- expect full table scan but got index range
select * from pojen X where eid=3;
select * from table(dbms_xplan.display_cursor(null,null));
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2302899125
-------------------------------------------------------------------------------------------------
| | Id | Operation | | Name | | Rows | Bytes | Cost (%CPU)| Time | | |
-------------------------------------------------------------------------------------------------
| | 0 | SELECT STATEMENT | | | | | 1 | | 19 | | 1 (0)| 00:00:01 | |
| | 1 | TABLE ACCESS BY INDEX ROWID BATCHED| POJEN | | | 1 | | 19 | | 1 (0)| 00:00:01 | |
| |* 2 | INDEX RANGE SCAN | | IDX_POEID | | 1 | | | | 1 (0)| 00:00:01 | |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EID"=3)
Note
-----
- SQL patch "patch_po2" used for this statement
BEGIN
DBMS_SQLDIAG.drop_sql_patch(name=>'patch_po2');
END;
/
select * from dba_sql_patches where name='patch_po';
I can see the SQL Patch has been applied in the note section, but more sure why optimizer still use the index range. (attempted with/without table alias. both yield the same output) Is there a internal limit that the query need to execute before SQL patch become effective?
Environment: 12.1.0.2, RedHat 6x64, noncdb, Jan 2019 patchset