Last week my colleague (Paul Reed – my new content provider with issues on his databases 🙂 ), had a problem where he needed to identify which baseline was using index
on a plan where collection table (like SELECT column FROM TABLE(:B1) ) was used.
When he tried DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE he got “ERROR: An error has happened, error code: 22905” which was related with the bug below.
DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE returns "ERROR: An error has happened, error code: 22905" [ID 1418186.1]
When he asked me, if there is a workaround, I was under the impression that dba_sql_plan_baselines has got the outline information, so I asked him to check if he can get the outline info.
He checked and make us realize the truth that cbo developers did not make outline information available to the public within dba_sql_plan_baselines table (I’m still thinking why not ??)
We checked the other options (dba_hist_active_sess_history.SQL_PLAN_OPERATION) and found out what we needed but this was not enough for me.
While I was thinking how we can get the outline, my collegue managed to get the answer accidentally which is the main reason, I’m writing this blog post.
To keep the baseline safe he was backing up them to staging table with DBMS_SPM.pack_stgtab_baseline procedure
and when he select from the staging table he saw that comp_data column is actually the outline information.
Here is how he did it with a little bit of polishing.
(I will be using the baseline generated on this post – dbms_xplan.display_sql_plan_baseline works for this but not important for the post purposes!!)
DBA_SQL_PLAN_BASELINE content
HR@ORACOS> @printtab 'select * from dba_sql_plan_baselines where plan_name="SQL_PLAN_13w748wknkcwd8576eb1f"' SIGNATURE : 1292784087274697613 SQL_HANDLE : SYS_SQL_11f0e4472549338d SQL_TEXT : select count(*), max(col2) from t1 where flag = :n PLAN_NAME : SQL_PLAN_13w748wknkcwd8576eb1f CREATOR : HR ORIGIN : MANUAL-LOAD PARSING_SCHEMA_NAME : HR DESCRIPTION : VERSION : 11.2.0.1.0 CREATED : 23-MAR-12 10.23.23.000000 LAST_MODIFIED : 23-MAR-12 10.23.23.000000 LAST_EXECUTED : 23-MAR-12 10.24.56.000000 LAST_VERIFIED : ENABLED : YES ACCEPTED : YES FIXED : NO AUTOPURGE : YES OPTIMIZER_COST : 2 MODULE : SQL*Plus ACTION : EXECUTIONS : 3 ELAPSED_TIME : 14772 CPU_TIME : 0 BUFFER_GETS : 9 DISK_READS : 0 DIRECT_WRITES : 0 ROWS_PROCESSED : 3 FETCHES : 3 END_OF_FETCH_COUNT : 3 ----------------- HR@ORACOS>
As you can see baseline is there but no outline info available to the public.
Lets create a staging table then pack the baseline.
Staging Table Creation
BEGIN DBMS_SPM.CREATE_STGTAB_BASELINE( table_name => 'SPM_STAGING', table_owner => 'HR' ); END; / PL/SQL procedure successfully completed.
Packing the baseline
SET SERVEROUTPUT ON DECLARE l_plans_packed PLS_INTEGER; BEGIN l_plans_packed := DBMS_SPM.pack_stgtab_baseline( table_name => 'SPM_STAGING', table_owner => 'HR', sql_handle=>'SYS_SQL_11f0e4472549338d', plan_name=>'SQL_PLAN_13w748wknkcwd8576eb1f' ); DBMS_OUTPUT.put_line('Plans Packed: ' || l_plans_packed); END; / Plans Packed: 1 PL/SQL procedure successfully completed.
Lets see what is inside the SPM_STAGING table where we packed the data into
Staging Table ContentÂ
R@ORACOS> HR@ORACOS> @printtab 'select * from spm_staging' VERSION : 2 SIGNATURE : 1292784087274697613 SQL_HANDLE : SYS_SQL_11f0e4472549338d OBJ_NAME : SQL_PLAN_13w748wknkcwd8576eb1f OBJ_TYPE : SQL_PLAN_BASELINE PLAN_ID : 2239163167 SQL_TEXT : select count(*), max(col2) from t1 where flag = :n CREATOR : HR ORIGIN : MANUAL-LOAD DESCRIPTION : DB_VERSION : 11.2.0.1.0 CREATED : 23-MAR-12 10.23.23.000000 LAST_MODIFIED : 23-MAR-12 10.23.23.000000 LAST_EXECUTED : 23-MAR-12 10.24.56.000000 LAST_VERIFIED : STATUS : 11 OPTIMIZER_COST : 2 MODULE : SQL*Plus ACTION : EXECUTIONS : 3 ELAPSED_TIME : 14772 CPU_TIME : 0 BUFFER_GETS : 9 DISK_READS : 0 DIRECT_WRITES : 0 ROWS_PROCESSED : 3 FETCHES : 3 END_OF_FETCH_COUNT : 3 CATEGORY : DEFAULT SQLFLAGS : 0 TASK_ID : TASK_EXEC_NAME : TASK_OBJ_ID : TASK_FND_ID : TASK_REC_ID : INUSE_FEATURES : 1 PARSE_CPU_TIME : PRIORITY : OPTIMIZER_ENV : E289FB89E126A80034011000AEF9C3E2CFFA331056414555519521105555551545545558591555449665851D5511058555555155515122555415A0EA0E5551454265455454449081566E001696A35615551403025415505AE126A800050402000002000000100000000100002000000208D007000000001000243303000101000038F8000400009299010000000800E126A80065646 40202643202320000020003020A0A05050A140002000032F4010000500A0A0A0A64E803000064E08003FFFF00000804020000080032 BIND_DATA : BEDA0B2001004F6C4EAD000101F001200369025931 PARSING_SCHEMA_NAME : HR COMP_DATA : <![CDATA[IGNORE_OPTIM_EMBEDDED_HINTS]]><![CDATA[OPTIMIZER_FEATURES_ENABLE('11.2.0.1')]]><![CDATA[DB_VERSION('11.2.0.1')]]><![CDATA[ALL_ROWS]]><![CDATA[OUTLINE_LEAF(@"SEL$1")]]><![CDATA[INDEX_RS_ASC(@"SEL$1" "T1"@"SEL$1" ("T1"."FLAG"))]]> ----------------- PL/SQL procedure successfully completed.
As you can see there are more columns inside the staging table and more importantly COMP_DATA column has got the outline information.
This way outline data is a bit hard to read. You can paste the information to an xml parser or you can use the query below to get a better output.
 COMP_DATA content  (outline information)
select extractvalue(value(d), '/hint') as outline_hints from xmltable('/outline_data/hint' passing ( select xmltype(comp_data) as xmlval from spm_staging ) ) d; OUTLINE_HINTS -------------------------------------------------------- IGNORE_OPTIM_EMBEDDED_HINTS OPTIMIZER_FEATURES_ENABLE('11.2.0.1') DB_VERSION('11.2.0.1') ALL_ROWS OUTLINE_LEAF(@"SEL$1") INDEX_RS_ASC(@"SEL$1" "T1"@"SEL$1" ("T1"."FLAG"))
It is simple for this query but It can be hard to guess the plan from this output what you can do is paste the outline information the the sql as hint like below.
Only line you need to remove is IGNORE_OPTIM_EMBEDDED_HINTS to avoid ignoring hints.
var n varchar2(2) exec :n := 'N1' select /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.1') DB_VERSION('11.2.0.1') ALL_ROWS OUTLINE_LEAF(@"SEL$1") INDEX_RS_ASC(@"SEL$1" "T1"@"SEL$1" ("T1"."FLAG")) */ count(*), max(col2) from t1 where flag = :n; PL/SQL procedure successfully completed. HR@ORACOS> 2 3 4 5 6 7 8 9 COUNT(*) MAX(COL2) ---------- -------------------------------------------------- 49999 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Generated plan with outline
HR@ORACOS> select * from table(dbms_xplan.display_cursor(null,null,'BASIC +OUTLINE')); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- EXPLAINED SQL STATEMENT: ------------------------ select /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.1') DB_VERSION('11.2.0.1') ALL_ROWS OUTLINE_LEAF(@"SEL$1") INDEX_RS_ASC(@"SEL$1" "T1"@"SEL$1" ("T1"."FLAG")) */ count(*), max(col2) from t1 where flag = :n Plan hash value: 3625400295 --------------------------------------------- | Id | Operation | Name | --------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | SORT AGGREGATE | | | 2 | TABLE ACCESS BY INDEX ROWID| T1 | | 3 | INDEX RANGE SCAN | I1 | --------------------------------------------- Outline Data ------------- /*+ BEGIN_OUTLINE_DATA IGNORE_OPTIM_EMBEDDED_HINTS OPTIMIZER_FEATURES_ENABLE('11.2.0.1') DB_VERSION('11.2.0.1') ALL_ROWS OUTLINE_LEAF(@"SEL$1") INDEX_RS_ASC(@"SEL$1" "T1"@"SEL$1" ("T1"."FLAG")) END_OUTLINE_DATA */
As you can see with this method we can find see outline for the baseline and with using that outline the plan inside the baseline (%99 of the time-sql should be same and also underlying objects)
You can use this method (till oracle provides outlines) when you hit the bugs below as well.
As long as you have a baseline it can be used. I also think about couple of other usages but I will keep them for future posts so you can stay tuned.
Bug 8366552: ORA-6502 WHEN TRYING TO DISPLAY PLANS FROM SQL BASELINE Bug 12335250: DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE CAUSES ORA-979 IF CURSOR_SHARING=FORCE/SIMI Bug 12833789: DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE RAISING ERROR 22905 Bug 10637509: DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE RECEIVES ORA-6502 Bug 10254875: DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE RETURNS: ERROR CODE: 1435
Bonus Material for Geeks and SYSDBA access owners
Same information is also available with the sql below –this sql is multi purpose so you can use it for sql_patches and sql_profiles
select * from ( SELECT sa.signature, st.sql_handle, so.name obj_name, decode(sa.obj_type, 1,'SQL_PROFILE', decode(sa.obj_type, 2,'SQL_PLAN_BASELINE',decode(sa.obj_type, 3,'SQL_PATCH', null))) obj_type, sa.plan_id, st.sql_text, sa.creator, dbms_smb_internal.map_origin_base_to_view(sa.origin, sa.obj_type) origin, sa.description, sa.version db_version, sa.created, sa.last_modified, so.last_executed, sa.last_verified, so.flags status, sa.optimizer_cost, sa.module, sa.action, sa.executions, sa.elapsed_time, sa.cpu_time, sa.buffer_gets, sa.disk_reads, sa.direct_writes, sa.rows_processed, sa.fetches, sa.end_of_fetch_count, sa.category, s.flags sqlflags, sa.task_id, sa.task_exec_name, sa.task_obj_id, sa.task_fnd_id, sa.task_rec_id, s.inuse_features, sa.parse_cpu_time, sa.priority, sa.optimizer_env, sa.bind_data, sa.parsing_schema_name, sd.comp_data FROM sql$ s, sqlobj$auxdata sa, sqlobj$ so, sql$text st, sqlobj$data sd WHERE sa.signature = s.signature and sa.signature = so.signature and sa.category = so.category and sa.obj_type = so.obj_type and sa.plan_id = so.plan_id and sa.signature = st.signature and sa.signature = sd.signature and sa.category = sd.category and sa.obj_type = sd.obj_type and sa.plan_id = sd.plan_id) v WHERE obj_name='SQL_PLAN_13w748wknkcwd8576eb1f' ----PLAN NAME and category is not null and sql_handle = 'SYS_SQL_11f0e4472549338d' -----PLAN HANDLE and obj_type = 'SQL_PLAN_BASELINE' and sql_text is not null
Thanks for the details.
Now the things are getting more visible because of You.
Keep going….
Thanks
Mohammed.
Comment by Mohammed Yousuf — April 12, 2012 @ 10:56 am
[…] https://coskan.wordpress.com/2012/04/11/when-dbms_xplan-display_sql_plan_baseline-fails-to-show-the-p… […]
Pingback by One simple example about Oracle SPM | leborchuk — August 19, 2012 @ 9:52 am