Second level XML elements
The following query is an attempt to find the second level (one below the root element other_xml
, that is) XML elements:
select
count(*),
t.name
from
-- v$sql_plan p,
dba_hist_sql_plan p,
xmlTable(
'/other_xml/*'
passing xmlType(p.other_xml)
columns
name varchar2(4000) path './name()'
) t
where
p.other_xml is not null
group by
t.name
order by
t.name;
On a 19c database, this query returned these elements:
- display_map
- hint_usage
- info
- outline_data
- peeked_binds
- qb_registry
- spd
- stats
info
Attributes of info
The following query finds the possible attribute names of the
<info>
element. In 19c, these are
select
count(*),
t.name
from
-- v$sql_plan p,
dba_hist_sql_plan p,
xmlTable(
'/other_xml/info/@*'
passing xmlType(p.other_xml)
columns
name varchar2(4000) path './name()'
) t
where
p.other_xml is not null
group by
t.name
order by
t.name;
Values of the type attribute
The values of the
type
attribute incude
- adaptive_plan
- baseline_repro_fail
- cardinality_feedback
- cpu_rate
- db_version
- derived_cpu_dop
- derived_io_dop
- dop
- dop_op_reason
- dop_reason
- dynamic_sampling
- has_user_tab
- idl_reason
- index_size
- io_rate
- nodeid/pflags
- parse_schema
- pdml_reason
- performance_feedback
- plan_hash
- plan_hash_2
- plan_hash_full
- px_ext_opns
- px_in_memory
- px_in_memory_imc
- queuing_reason
- slave_parse
- sql_patch
These values can be queried like so:
select
count(*),
t.name
from
-- v$sql_plan p,
dba_hist_sql_plan p,
xmlTable(
'/other_xml/info/@type'
passing xmlType(p.other_xml)
columns
name varchar2(4000) path '.'
) t
where
p.other_xml is not null
group by
t.name
order by
t.name;
hint_usage
--
-- As so often, Frank Pachot's insights were very helpful
-- https://franckpachot.medium.com/oracle-19c-hint-usage-reporting-345563a461f0
--
with h as (
select
-- plan.sql_id,
-- other_xml,
plan.qblock_name query_block_name_plan,
qb.name query_block_name,
qb.status query_block_status ,
-- qb.hints.getClobVal() hints,
-- hint.o, -- ???
case hint.status
when 'PE' then 'Parse error'
when 'UR' then 'Unresolved'
when 'NU' then 'Not used (NU)'
when 'PU' then 'Not used (PU)'
else hint.status
end hint_status ,
--
lower(regexp_replace(hint, '([^(]*).*' , '\1')) hint_name ,
lower(regexp_substr(hint, '\((*.*)\)' )) hint_arguments,
hint.hint , -- Text of hint
hint.reason, -- index specified in the hint doesn't exist,
-- rejected by IGNORE_OPTIM_EMBEDDED_HINTS
-- same QB_NAME hints for different query blocks
-- ORDER_SUBQ referenced query block name, which cannot be found
-- hint overridden by another in parent query block
hint.obj_alias,
hint.hint_ts
from
-- plan_table plan,
-- v$sql_plan plan,
dba_hist_sql_plan plan,
xmlTable('/*/hint_usage/q' passing xmltype(other_xml)
columns
name VARCHAR2(4000) path './n',
status varchar2( 3) path '@st', -- @st = status ?
hints xmlType path './*'
) qb,
--
-- Search for hints with '//h' because
-- the <h> tag sometimes occurs directly below <hint_usage> and
-- sometimes below <t>.
--
xmlTable('//h' passing qb.hints
columns
o varchar2( 3) path '@o' , -- EM or OU or ?
status varchar2( 3) path '@st' ,
hint varchar2(4000) path 'x' , -- The text of the hint (clob?)
reason varchar2(4000) path 'r' ,
obj_alias varchar2(4000) path './../f',
hint_ts varchar2( 3) path './../@st'
) hint
where
other_xml is not null
)
select
*
-- hint_status,
-- hint_name,
-- hint_arguments
-- hint,
-- obj_alias,
-- hint_ts
-- count(*), hint_name, hint_status
from
h
;
Querying OTHER_XML with XPATH expressions
other_xml
can be queried with
XPath expressions.
with x as (
select xmlType(other_xml) other_xml from v$sql_plan where other_xml is not null
)
select
extractvalue(other_xml, '/*/info[@type = "plan_hash"]' ) plan_hash,
extractvalue(other_xml, '/*/info[@type = "adaptive_plan"]' ) adaptive_plan,
extractvalue(other_xml, '/*/info[@type = "sql_profile"]' ) sql_profile,
extractvalue(other_xml, '/*/info[@type = "sql_patch"]' ) sql_patch,
extractvalue(other_xml, '/*/info[@type = "baseline"]' ) baseline,
extractvalue(other_xml, '/*/info[@type = "outline"]' ) outline,
extractvalue(other_xml, '/*/info[@type = "dynamic_sampling"]' ) dynamic_sampling,
extractvalue(other_xml, '/*/info[@type = "dop"]' ) dop,
extractvalue(other_xml, '/*/info[@type = "dop_reason"]' ) dop_reason,
extractvalue(other_xml, '/*/info[@type = "pdml_reason"]' ) pdml_reason,
extractvalue(other_xml, '/*/info[@type = "idl_reason"]' ) idl_reason,
extractvalue(other_xml, '/*/info[@type = "queuing_reason"]' ) queuing_reason,
extractvalue(other_xml, '/*/info[@type = "px_in_memory"]' ) px_in_memory,
extractvalue(other_xml, '/*/info[@type = "px_in_memory_imc"]' ) px_in_memory_imc,
extractvalue(other_xml, '/*/info[@type = "row_shipping"]' ) row_shipping,
extractvalue(other_xml, '/*/info[@type = "index_size"]' ) index_size,
extractvalue(other_xml, '/*/info[@type = "result_checksum"]' ) result_checksum,
extractvalue(other_xml, '/*/info[@type = "cardinality_feedback"]' ) cardinality_feedback,
extractvalue(other_xml, '/*/info[@type = "performance_feedback"]' ) performance_feedback,
extractvalue(other_xml, '/*/info[@type = "rely_constraint"]' ) rely_constraint,
extractvalue(other_xml, '/*/info[@type = "xml_suboptimal"]' ) xml_suboptimal,
extractvalue(other_xml, '/*/spd/cu' ) spd_cu,
extractvalue(other_xml, '/*/info[@type = "gtt_session_st"]' ) gtt_session_st,
extractvalue(other_xml, '/*/info[@type = "gather_stats_on_conventional_dml"]' ) gather_stats_on_cnvtl_dml,
extractvalue(other_xml, '/*/info[@type = "optimizer_use_stats_on_conventional_dml"]') opt_use_stats_on_cnvtl_dml,
extractvalue(other_xml, '/*/info[@type = "slave_parse"]' ) slave_parse,
extractvalue(other_xml, '/*/info[@type = "baseline_repro_fail"]' ) baseline_repro_fail,
extractvalue(other_xml, '/*/info[@type = "cross_shard_query"]' ) cross_shard_query,
extractvalue(other_xml, '/*/info[@type = "shard_id"]' ) shard_id,
extract (other_xml, '/*/hint_usage').getClobVal()
from
x
;