2026-03-12 20:23:15
This commit is contained in:
7
Kevin_Meade/afiedt.buf
Normal file
7
Kevin_Meade/afiedt.buf
Normal file
@@ -0,0 +1,7 @@
|
||||
SELECT column_id,
|
||||
column_name,
|
||||
histogram
|
||||
FROM user_tab_columns
|
||||
WHERE table_name = 'R3'
|
||||
ORDER BY column_id
|
||||
/
|
||||
97
Kevin_Meade/loadplanfromcache11g.sql
Normal file
97
Kevin_Meade/loadplanfromcache11g.sql
Normal file
@@ -0,0 +1,97 @@
|
||||
--
|
||||
-- load qep information into the plan_table from gv$sql_plan
|
||||
--
|
||||
-- requires you to identify the inst_id,sql_id,child_number first
|
||||
--
|
||||
-- parameter 1 = inst_id
|
||||
-- parameter 2 = sql_id
|
||||
-- parameter 3 = child_number
|
||||
--
|
||||
-- @loadplanfromcache11g.sql 1 6zcb0r0rch025 0
|
||||
--
|
||||
-- then use the normal plan_table scripts to get the goodness
|
||||
--
|
||||
-- @showplan11g
|
||||
-- @showplandatamodel11g
|
||||
-- ...
|
||||
--
|
||||
|
||||
insert into plan_table
|
||||
(
|
||||
PLAN_ID
|
||||
,TIMESTAMP
|
||||
,REMARKS
|
||||
,OPERATION
|
||||
,OPTIONS
|
||||
,OBJECT_NODE
|
||||
,OBJECT_OWNER
|
||||
,OBJECT_NAME
|
||||
,OBJECT_ALIAS
|
||||
,object_instance
|
||||
,OBJECT_TYPE
|
||||
,OPTIMIZER
|
||||
,SEARCH_COLUMNS
|
||||
,ID
|
||||
,PARENT_ID
|
||||
,DEPTH
|
||||
,POSITION
|
||||
,COST
|
||||
,CARDINALITY
|
||||
,BYTES
|
||||
,OTHER_TAG
|
||||
,PARTITION_START
|
||||
,PARTITION_STOP
|
||||
,PARTITION_ID
|
||||
,OTHER
|
||||
,OTHER_XML
|
||||
,DISTRIBUTION
|
||||
,CPU_COST
|
||||
,IO_COST
|
||||
,TEMP_SPACE
|
||||
,ACCESS_PREDICATES
|
||||
,FILTER_PREDICATES
|
||||
,PROJECTION
|
||||
,TIME
|
||||
,QBLOCK_NAME
|
||||
)
|
||||
select
|
||||
nvl((select max(plan_id) from plan_table),0)+1 plan_id
|
||||
,TIMESTAMP
|
||||
,REMARKS
|
||||
,OPERATION
|
||||
,OPTIONS
|
||||
,OBJECT_NODE
|
||||
,OBJECT_OWNER
|
||||
,OBJECT_NAME
|
||||
,OBJECT_ALIAS
|
||||
,OBJECT# object_instance
|
||||
,OBJECT_TYPE
|
||||
,OPTIMIZER
|
||||
,SEARCH_COLUMNS
|
||||
,ID
|
||||
,PARENT_ID
|
||||
,DEPTH
|
||||
,POSITION
|
||||
,COST
|
||||
,CARDINALITY
|
||||
,BYTES
|
||||
,OTHER_TAG
|
||||
,PARTITION_START
|
||||
,PARTITION_STOP
|
||||
,PARTITION_ID
|
||||
,OTHER
|
||||
,OTHER_XML
|
||||
,DISTRIBUTION
|
||||
,CPU_COST
|
||||
,IO_COST
|
||||
,TEMP_SPACE
|
||||
,ACCESS_PREDICATES
|
||||
,FILTER_PREDICATES
|
||||
,PROJECTION
|
||||
,TIME
|
||||
,QBLOCK_NAME
|
||||
from gv$sql_plan
|
||||
where inst_id = &&1
|
||||
and sql_id = '&&2'
|
||||
and child_number = &&3
|
||||
/
|
||||
103
Kevin_Meade/loadplanfromhist11g.sql
Normal file
103
Kevin_Meade/loadplanfromhist11g.sql
Normal file
@@ -0,0 +1,103 @@
|
||||
--
|
||||
-- load qep information into the plan_table from DBA_HIST_SQL_PLAN (history of monitored plans)
|
||||
--
|
||||
-- requires you to identify the sql_id and date of when you want your plan
|
||||
-- does a bob barker lookup based on the date, for the sql_id supplied
|
||||
-- note use of +1 second to the date in order to account for the millseconds in the timestamp
|
||||
-- note also the use of a specific format mask 'rrrrmmddhh24miss'
|
||||
-- often you will need to guess about the time unless you know it from some other place
|
||||
--
|
||||
-- parameter 1 = sql_id
|
||||
-- parameter 2 = timestamp (in the right format)
|
||||
--
|
||||
-- @loadplanfromhist11g.sql 6zcb0r0rch025 2014080212:10:03
|
||||
--
|
||||
-- then use the normal plan_table scripts to get the goodness
|
||||
--
|
||||
-- @showplan11g
|
||||
-- @showplandatamodel11g
|
||||
-- ...
|
||||
--
|
||||
insert into plan_table
|
||||
(
|
||||
PLAN_ID
|
||||
,TIMESTAMP
|
||||
,REMARKS
|
||||
,OPERATION
|
||||
,OPTIONS
|
||||
,OBJECT_NODE
|
||||
,OBJECT_OWNER
|
||||
,OBJECT_NAME
|
||||
,OBJECT_ALIAS
|
||||
,object_instance
|
||||
,OBJECT_TYPE
|
||||
,OPTIMIZER
|
||||
,SEARCH_COLUMNS
|
||||
,ID
|
||||
,PARENT_ID
|
||||
,DEPTH
|
||||
,POSITION
|
||||
,COST
|
||||
,CARDINALITY
|
||||
,BYTES
|
||||
,OTHER_TAG
|
||||
,PARTITION_START
|
||||
,PARTITION_STOP
|
||||
,PARTITION_ID
|
||||
,OTHER
|
||||
,OTHER_XML
|
||||
,DISTRIBUTION
|
||||
,CPU_COST
|
||||
,IO_COST
|
||||
,TEMP_SPACE
|
||||
,ACCESS_PREDICATES
|
||||
,FILTER_PREDICATES
|
||||
,PROJECTION
|
||||
,TIME
|
||||
,QBLOCK_NAME
|
||||
)
|
||||
select
|
||||
nvl((select max(plan_id) from plan_table),0)+1 plan_id
|
||||
,TIMESTAMP
|
||||
,REMARKS
|
||||
,OPERATION
|
||||
,OPTIONS
|
||||
,OBJECT_NODE
|
||||
,OBJECT_OWNER
|
||||
,OBJECT_NAME
|
||||
,OBJECT_ALIAS
|
||||
,OBJECT# object_instance
|
||||
,OBJECT_TYPE
|
||||
,OPTIMIZER
|
||||
,SEARCH_COLUMNS
|
||||
,ID
|
||||
,PARENT_ID
|
||||
,DEPTH
|
||||
,POSITION
|
||||
,COST
|
||||
,CARDINALITY
|
||||
,BYTES
|
||||
,OTHER_TAG
|
||||
,PARTITION_START
|
||||
,PARTITION_STOP
|
||||
,PARTITION_ID
|
||||
,OTHER
|
||||
,OTHER_XML
|
||||
,DISTRIBUTION
|
||||
,CPU_COST
|
||||
,IO_COST
|
||||
,TEMP_SPACE
|
||||
,ACCESS_PREDICATES
|
||||
,FILTER_PREDICATES
|
||||
,PROJECTION
|
||||
,TIME
|
||||
,QBLOCK_NAME
|
||||
from dba_hist_sql_plan
|
||||
where sql_id = '&&1'
|
||||
and timestamp = (
|
||||
select max(timestamp)
|
||||
from dba_hist_sql_plan
|
||||
where sql_id = '&&1'
|
||||
and timestamp <= to_date('&&2','rrrrmmddhh24miss')+1/24/60/60
|
||||
)
|
||||
/
|
||||
113
Kevin_Meade/showallscanrates.sql
Normal file
113
Kevin_Meade/showallscanrates.sql
Normal file
@@ -0,0 +1,113 @@
|
||||
--
|
||||
-- show have fast scan operations
|
||||
-- (sorting / hashing / table scans / index scans) will take
|
||||
--
|
||||
-- provides a MB/second metric that can be used to compare different systems
|
||||
-- has plenty of flaws yet still works great
|
||||
--
|
||||
-- also provides an expected end time for the operation
|
||||
-- though this can be misleading
|
||||
--
|
||||
-- usage is: @SHOWALLSCANRATES
|
||||
--
|
||||
|
||||
--clear breaks
|
||||
--clear computes
|
||||
--clear columns
|
||||
col time_remaining head 'Seconds|Remaining'
|
||||
col scanned_blocks head 'Scanned Blocks|or Indexes'
|
||||
col all_blocks head 'All Blocks|or Indexes'
|
||||
col blocks_remaining head 'Blocks|or Indexes|Remaining' noprint
|
||||
col opname format a16
|
||||
col target format a40
|
||||
col username format a15
|
||||
col MB_per_Second form 990.0 head 'MB/s'
|
||||
col pct_scanned head '%Scanned' format 990.00
|
||||
col predicted_runtime_seconds head 'Estmd.|Runtime|Seconds'
|
||||
col total_blocks head 'Total|Blocks|or|Indexes'
|
||||
col sid format 99990
|
||||
col block_size format 99990 head 'Block|Size'
|
||||
col id_passes_temp format a25
|
||||
break on inst_id skip page
|
||||
|
||||
with
|
||||
scan_data as (
|
||||
select
|
||||
to_number(
|
||||
substr(a.message
|
||||
,instr(a.message,': ',1,2)+2
|
||||
,instr(a.message,' out of ',1,1)-instr(a.message,': ',1,2)-1
|
||||
)
|
||||
)
|
||||
/ to_number(
|
||||
substr(a.message
|
||||
,instr(a.message,' out of ',1,1)+8
|
||||
,instr(a.message,' ',instr(a.message,' out of ',1,1)+8)-instr(a.message,' out of ',1,1)-7
|
||||
)
|
||||
) *100 pct_scanned
|
||||
, to_number(
|
||||
substr(a.message
|
||||
,instr(a.message,' out of ',1,1)+8
|
||||
,instr(a.message,' ',instr(a.message,' out of ',1,1)+8)-instr(a.message,' out of ',1,1)-7
|
||||
)
|
||||
)
|
||||
- to_number(
|
||||
substr(a.message
|
||||
,instr(a.message,': ',1,2)+2
|
||||
,instr(a.message,' out of ',1,1)-instr(a.message,': ',1,2)-1
|
||||
)
|
||||
) blocks_remaining
|
||||
, a.time_remaining
|
||||
, a.opname
|
||||
, to_number(b.value) block_size
|
||||
, a.target
|
||||
, a.sid
|
||||
, a.inst_id
|
||||
, a.username
|
||||
, a.sql_hash_value
|
||||
from (
|
||||
select
|
||||
replace(gv$session_longops.message,'RMAN:','RMAN') message
|
||||
, gv$session_longops.time_remaining
|
||||
, gv$session_longops.opname
|
||||
, nvl(gv$session_longops.target,replace(gv$session_longops.target_desc,'Table ')) target
|
||||
, gv$session_longops.sid
|
||||
, gv$session_longops.inst_id
|
||||
, gv$session_longops.username
|
||||
, gv$session_longops.sql_hash_value
|
||||
from gv$session_longops
|
||||
, gv$session
|
||||
where gv$session_longops.sid = gv$session.sid
|
||||
and gv$session_longops.inst_id = gv$session.inst_id
|
||||
and gv$session_longops.sid = gv$session.sid
|
||||
and gv$session_longops.serial# = gv$session.serial#
|
||||
and gv$session_longops.time_remaining > 0
|
||||
) a
|
||||
,(select value from gv$parameter where name = 'db_block_size' and rownum = 1) b
|
||||
)
|
||||
select
|
||||
scan_data.inst_id
|
||||
, round(blocks_remaining*block_size/1024/1024/time_remaining,1) MB_per_Second
|
||||
, scan_data.time_remaining
|
||||
, round(time_remaining/(1-pct_scanned/100)) predicted_runtime_seconds
|
||||
, scan_data.pct_scanned
|
||||
, scan_data.blocks_remaining
|
||||
, round(blocks_remaining/(1-pct_scanned/100)) total_blocks
|
||||
, scan_data.opname
|
||||
, scan_data.BLOCK_SIZE
|
||||
, scan_data.target
|
||||
, (
|
||||
select
|
||||
max(operation_id)||':'||DECODE(MAX(NUMBER_PASSES),0,'OPTIMAL',1,'ONE-PASS',NULL,NULL,'MULTI-PASS('||max(number_passes)||')')||DECODE(max(TEMPSEG_SIZE),NULL,NULL,','||round(max(TEMPSEG_SIZE)/1024/1024)||'M')
|
||||
from gv$sql_workarea_active
|
||||
where gv$sql_workarea_active.sid = scan_data.sid
|
||||
and gv$sql_workarea_active.inst_id = scan_data.inst_id
|
||||
-- and scan_data.opname in ('Hash Join','Sort Output')
|
||||
-- and gv$sql_workarea_active.OPERATION_TYPE in ('HASH-JOIN','SORT','WINDOW (SORT)','GROUP BY (SORT)')
|
||||
) id_passes_temp
|
||||
, scan_data.sid
|
||||
, scan_data.username
|
||||
, scan_data.sql_hash_value
|
||||
from scan_data
|
||||
order by inst_id,username,sid,time_remaining
|
||||
/
|
||||
12
Kevin_Meade/showallworkareas.sql
Normal file
12
Kevin_Meade/showallworkareas.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
--
|
||||
-- show work areas in use
|
||||
--
|
||||
|
||||
col SQL_EXEC_START noprint
|
||||
col SQL_EXEC_ID noprint
|
||||
col WORKAREA_ADDRESS noprint
|
||||
col OPERATION_TYPE format a20 trunc
|
||||
col active_time noprint
|
||||
col expected_size noprint
|
||||
|
||||
select * from gv$sql_workarea_active;
|
||||
76
Kevin_Meade/showcolstats.sql
Normal file
76
Kevin_Meade/showcolstats.sql
Normal file
@@ -0,0 +1,76 @@
|
||||
--
|
||||
-- show all column stats for columns in the specified table
|
||||
-- requires the function KEV_RAW_TO_STRING
|
||||
-- very usefull for looking at column recorded HIGH/LOW
|
||||
--
|
||||
-- parameter 1 = owner
|
||||
-- parameter 2 = table_name
|
||||
--
|
||||
-- usage is: @SHOWCOLSTATS <owner> <table_name>
|
||||
--
|
||||
|
||||
/*
|
||||
CREATE OR replace FUNCTION kev_raw_to_string (rawval RAW, TYPE VARCHAR2) RETURN VARCHAR2
|
||||
IS
|
||||
cn NUMBER;
|
||||
cv VARCHAR2(32);
|
||||
cd DATE;
|
||||
cnv NVARCHAR2(32);
|
||||
cr ROWID;
|
||||
cc CHAR(32);
|
||||
BEGIN
|
||||
IF ( TYPE = 'NUMBER' ) THEN
|
||||
dbms_stats.Convert_raw_value(rawval, cn);
|
||||
RETURN '"'||cn||'"';
|
||||
ELSIF ( TYPE = 'VARCHAR2' ) THEN
|
||||
dbms_stats.Convert_raw_value(rawval, cv);
|
||||
RETURN '"'||cv||'"';
|
||||
ELSIF ( TYPE = 'DATE' ) THEN
|
||||
dbms_stats.Convert_raw_value(rawval, cd);
|
||||
RETURN '"'||to_char(cd,'dd-mon-rrrr.hh24:mi:ss')||'"';
|
||||
ELSIF ( TYPE = 'NVARCHAR2' ) THEN
|
||||
dbms_stats.Convert_raw_value(rawval, cnv);
|
||||
RETURN '"'||cnv||'"';
|
||||
ELSIF ( TYPE = 'ROWID' ) THEN
|
||||
dbms_stats.Convert_raw_value(rawval, cr);
|
||||
RETURN '"'||cnv||'"';
|
||||
ELSIF ( TYPE = 'CHAR' ) THEN
|
||||
dbms_stats.Convert_raw_value(rawval, cc);
|
||||
RETURN '"'||cc||'"';
|
||||
ELSE
|
||||
RETURN '"UNSUPPORTED DATA_TYPE"';
|
||||
END IF;
|
||||
exception when others then
|
||||
return '--- conversion error ---';
|
||||
END;
|
||||
/
|
||||
*/
|
||||
col low_value format a30
|
||||
col high_value format a30
|
||||
col last_analyzed format a22
|
||||
--select table_name,column_name, num_distinct, num_nulls, num_buckets, sample_size,last_analyzed
|
||||
select
|
||||
OWNER
|
||||
, TABLE_NAME
|
||||
, COLUMN_NAME
|
||||
, NUM_DISTINCT
|
||||
, NUM_NULLS
|
||||
, NUM_BUCKETS
|
||||
, SAMPLE_SIZE
|
||||
, AVG_COL_LEN
|
||||
, DENSITY
|
||||
, TO_CHAR(LAST_ANALYZED,'dd-mon-rrrr.hh24:mi:ss') last_analyzed
|
||||
, GLOBAL_STATS
|
||||
, USER_STATS
|
||||
, km21378.kev_raw_to_string (LOW_VALUE,(select data_type from dba_tab_columns b where b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name)) LOW_VALUE
|
||||
, km21378.kev_raw_to_string (HIGH_VALUE,(select data_type from dba_tab_columns b where b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name)) HIGH_VALUE
|
||||
from dba_tab_col_statistics a
|
||||
where (owner,table_name) in
|
||||
(
|
||||
(upper('&&1'),upper('&&2'))
|
||||
)
|
||||
--and (column_name = 'ROW_TERM_DATE$' or num_buckets > 1)
|
||||
order by TABLE_NAME,COLUMN_NAME
|
||||
/
|
||||
|
||||
|
||||
39
Kevin_Meade/showconstraints.sql
Normal file
39
Kevin_Meade/showconstraints.sql
Normal file
@@ -0,0 +1,39 @@
|
||||
--
|
||||
-- given a table
|
||||
-- show is PK/UK/FK constraints
|
||||
-- and FK constraints that point to it
|
||||
--
|
||||
-- usage is: @SHOWCONSTRAINTS <owner> <table_name>
|
||||
--
|
||||
|
||||
break on constraint_name skip 1 on parent_table_name
|
||||
col column_name format a30
|
||||
col sort_order noprint
|
||||
col select_id noprint
|
||||
|
||||
select a.owner,a.table_name,a.constraint_name,a.constraint_type,c.column_name,b.owner parent_child_owner,b.table_name parent_child_table_name,b.constraint_type,a.index_name,decode(a.constraint_type,'P',1,'U',2) sort_order,1 select_id
|
||||
from dba_constraints a
|
||||
,dba_constraints b
|
||||
,dba_cons_columns c
|
||||
where a.owner = upper('&&1')
|
||||
and a.table_name = upper('&&2')
|
||||
and a.r_owner = b.owner(+)
|
||||
and a.r_constraint_name = b.constraint_name(+)
|
||||
and a.owner = c.owner
|
||||
and a.constraint_name = c.constraint_name
|
||||
and a.constraint_type != 'C'
|
||||
union all
|
||||
select a.owner,a.table_name,a.constraint_name,a.constraint_type,c.column_name,b.owner parent_child_owner,b.table_name parent_child_table_name,b.constraint_type,a.index_name,decode(a.constraint_type,'P',1,'U',2) sort_order,2 select_id
|
||||
from dba_constraints a
|
||||
,dba_constraints b
|
||||
,dba_cons_columns c
|
||||
where b.owner = upper('&&1')
|
||||
and b.table_name = upper('&&2')
|
||||
and b.constraint_type in ('P','U')
|
||||
and a.r_owner = b.owner
|
||||
and a.r_constraint_name = b.constraint_name
|
||||
and b.table_name != a.table_name
|
||||
and a.owner = c.owner
|
||||
and a.constraint_name = c.constraint_name
|
||||
order by select_id,sort_order,owner,table_name,constraint_name,column_name
|
||||
/
|
||||
69
Kevin_Meade/showgencardinalitycheckcode.sql
Normal file
69
Kevin_Meade/showgencardinalitycheckcode.sql
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
|
||||
@gencardinalitycheckcode.sql dwstage ods_pega_report_group_assoc CASEID,CVRGPLNNBR,PLCYID,PEGARPRTGRPSTRTDT,LSSUNTNBR,FNDNGMTHDPLNNBR,EMPGRPID,CVRGCTGRYCD,CVRGTYPCD,FNDNGMTHDCD,RPRTGRPID,ROW_TERM_DATE,SOURCE 1
|
||||
@gencardinalitycheckcode.sql dwstage ods_pega_report_group_assoc CASEID,CVRGPLNNBR,PLCYID,PEGARPRTGRPSTRTDT,LSSUNTNBR,FNDNGMTHDPLNNBR,EMPGRPID,CVRGCTGRYCD,CVRGTYPCD,FNDNGMTHDCD,RPRTGRPID,ROW_TERM_DATE,SOURCE 2
|
||||
@gencardinalitycheckcode.sql dwstage ods_pega_report_group_assoc CASEID,CVRGPLNNBR,PLCYID,PEGARPRTGRPSTRTDT,LSSUNTNBR,FNDNGMTHDPLNNBR,EMPGRPID,CVRGCTGRYCD,CVRGTYPCD,FNDNGMTHDCD,RPRTGRPID,ROW_TERM_DATE,SOURCE 3
|
||||
@gencardinalitycheckcode.sql dwstage ods_pega_report_group_assoc CASEID,CVRGPLNNBR,PLCYID,PEGARPRTGRPSTRTDT,LSSUNTNBR,FNDNGMTHDPLNNBR,EMPGRPID,CVRGCTGRYCD,CVRGTYPCD,FNDNGMTHDCD,RPRTGRPID,ROW_TERM_DATE,SOURCE 4
|
||||
|
||||
|
||||
use this to get a starting point for best combination of columns based on distinct
|
||||
note this still have the NULLS issue maybe (how do we handle columns with large % of null values)
|
||||
but ignoring this, the technique is pretty solid
|
||||
|
||||
generate code and run it to find out how distinct different combinations of columns are
|
||||
give some list of columns generate the possible combinations of columns restricted to a limited number (exp. combinations of N things taken M at a time)
|
||||
results should point you to a good starting set of columns for an index given you list of columns you are intersted in
|
||||
from this you use GENCARDINALITYCHECKCODE2.SQL
|
||||
|
||||
*/
|
||||
|
||||
with
|
||||
table_data as (
|
||||
select owner,table_name
|
||||
from dba_tables
|
||||
where owner = upper('&&1')
|
||||
and table_name = upper('&&2')
|
||||
)
|
||||
, column_list as (
|
||||
select dba_tab_columns.owner,dba_tab_columns.table_name,dba_tab_columns.column_name
|
||||
from dba_tab_columns
|
||||
,table_data
|
||||
where dba_tab_columns.owner = table_data.owner
|
||||
and dba_tab_columns.table_name = table_data.table_name
|
||||
and instr(','||upper('&&3')||',',','||dba_tab_columns.column_name||',') > 0
|
||||
)
|
||||
, column_expression as (
|
||||
select a.*
|
||||
,length(sys_connect_by_path(a.column_name,','))-length(replace(sys_connect_by_path(a.column_name,','),',')) column_count
|
||||
,substr(sys_connect_by_path(a.column_name,'||'',''||'),8) column_expression
|
||||
from column_list a
|
||||
connect by prior a.column_name < a.column_name
|
||||
)
|
||||
select 'clear columns' from dual union all
|
||||
select 'col column_count newline' from dual union all
|
||||
select 'col COLUMN_EXPRESSION format a800' from dual union all
|
||||
select 'set linesize 999' from dual union all
|
||||
select 'set pagesize 0' from dual union all
|
||||
select 'set trimspool on' from dual union all
|
||||
select 'set trimout on' from dual union all
|
||||
--select 'set feedback off' from dual union all
|
||||
--select 'set timing off' from dual union all
|
||||
--select 'set time off' from dual union all
|
||||
select '--owner table_name rowcount number_of_columns column_combo_cardinality column_expression' from dual union all
|
||||
select 'select '''||table_data.owner||''' owner,'''||table_data.table_name||''' table_name,count(*) table_rowcount'
|
||||
from table_data
|
||||
union all
|
||||
select *
|
||||
from (
|
||||
select ' ,'||column_expression.column_count||' column_count,count(distinct '||column_expression.column_expression||') expression_rowcount,'''||replace(column_expression.column_expression,chr(39),chr(39)||chr(39))||''' column_expression'
|
||||
from column_expression
|
||||
where column_count <= &&4
|
||||
order by column_count,column_expression
|
||||
)
|
||||
union all
|
||||
select 'from '||table_data.owner||'.'||table_data.table_name
|
||||
from table_data
|
||||
union all
|
||||
select '/'
|
||||
from table_data
|
||||
/
|
||||
29
Kevin_Meade/showhistograms.sql
Normal file
29
Kevin_Meade/showhistograms.sql
Normal file
@@ -0,0 +1,29 @@
|
||||
--
|
||||
-- shows the histogram for a specific column
|
||||
-- very usefull for showing when statistics might not help
|
||||
--
|
||||
-- parameter 1 = owner
|
||||
-- parameter 2 = table_name
|
||||
-- parameter 3 = column_name
|
||||
--
|
||||
-- usage is: @SHOWHISTOGRAM <owner> <table_name> <column_name>
|
||||
--
|
||||
|
||||
COLUMN endpoint_actual_value noprint
|
||||
COLUMN actual_value ON FORMAT a30
|
||||
col column format a30
|
||||
|
||||
|
||||
select b.*
|
||||
,round(ratio_to_report(cardinality) over(partition by owner,table_name,column_name)*100) pct
|
||||
,endpoint_actual_value actual_value
|
||||
from (
|
||||
select a.*
|
||||
,ENDPOINT_NUMBER-nvl(lag(ENDPOINT_NUMBER) over(partition by owner,table_name,column_name order by endpoint_number),0) cardinality
|
||||
from dba_histograms a
|
||||
where owner = upper('&&1')
|
||||
and table_name = upper('&&2')
|
||||
and column_name = upper('&&3')
|
||||
) b
|
||||
order by owner,table_name,column_name,ENDPOINT_NUMBER
|
||||
/
|
||||
24
Kevin_Meade/showindexes.sql
Normal file
24
Kevin_Meade/showindexes.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
--
|
||||
-- for the given table
|
||||
-- list the indexes on the table
|
||||
--
|
||||
-- parameter 1 = owner
|
||||
-- parameter 2 = table_name
|
||||
--
|
||||
-- usage is: @SHOWINDEXES <owner> <table_name>
|
||||
--
|
||||
|
||||
set verify off
|
||||
|
||||
break on index_name skip 1
|
||||
col column_name format a30
|
||||
|
||||
select index_name,column_name
|
||||
,(select index_type from dba_indexes b where b.owner = a.index_owner and b.index_name = a.index_name) index_type
|
||||
,(select uniqueness from dba_indexes b where b.owner = a.index_owner and b.index_name = a.index_name) uniqueness
|
||||
,(select tablespace_name from dba_indexes b where b.owner = a.index_owner and b.index_name = a.index_name) tablespace_name
|
||||
from dba_ind_columns a
|
||||
where table_name = upper('&&2')
|
||||
and table_owner = upper('&&1')
|
||||
order by 1,column_position
|
||||
/
|
||||
101
Kevin_Meade/showmyscanrates.sql
Normal file
101
Kevin_Meade/showmyscanrates.sql
Normal file
@@ -0,0 +1,101 @@
|
||||
--clear breaks
|
||||
--clear computes
|
||||
--clear columns
|
||||
col time_remaining head 'Seconds|Remaining'
|
||||
col scanned_blocks head 'Scanned Blocks|or Indexes'
|
||||
col all_blocks head 'All Blocks|or Indexes'
|
||||
col blocks_remaining head 'Blocks|or Indexes|Remaining' noprint
|
||||
col opname format a16
|
||||
col target format a40
|
||||
col username format a15
|
||||
col MB_per_Second form 990.0 head 'MB/s'
|
||||
col pct_scanned head '%Scanned' format 990.00
|
||||
col predicted_runtime_seconds head 'Estmd.|Runtime|Seconds'
|
||||
col total_blocks head 'Total|Blocks|or|Indexes'
|
||||
col sid format 99990
|
||||
col block_size format 99990 head 'Block|Size'
|
||||
col id_passes_temp format a25
|
||||
break on inst_id skip page
|
||||
|
||||
with
|
||||
scan_data as (
|
||||
select
|
||||
to_number(
|
||||
substr(a.message
|
||||
,instr(a.message,': ',1,2)+2
|
||||
,instr(a.message,' out of ',1,1)-instr(a.message,': ',1,2)-1
|
||||
)
|
||||
)
|
||||
/ to_number(
|
||||
substr(a.message
|
||||
,instr(a.message,' out of ',1,1)+8
|
||||
,instr(a.message,' ',instr(a.message,' out of ',1,1)+8)-instr(a.message,' out of ',1,1)-7
|
||||
)
|
||||
) *100 pct_scanned
|
||||
, to_number(
|
||||
substr(a.message
|
||||
,instr(a.message,' out of ',1,1)+8
|
||||
,instr(a.message,' ',instr(a.message,' out of ',1,1)+8)-instr(a.message,' out of ',1,1)-7
|
||||
)
|
||||
)
|
||||
- to_number(
|
||||
substr(a.message
|
||||
,instr(a.message,': ',1,2)+2
|
||||
,instr(a.message,' out of ',1,1)-instr(a.message,': ',1,2)-1
|
||||
)
|
||||
) blocks_remaining
|
||||
, a.time_remaining
|
||||
, a.opname
|
||||
, to_number(b.value) block_size
|
||||
, a.target
|
||||
, a.sid
|
||||
, a.inst_id
|
||||
, a.username
|
||||
, a.sql_hash_value
|
||||
from (
|
||||
select
|
||||
replace(gv$session_longops.message,'RMAN:','RMAN') message
|
||||
, gv$session_longops.time_remaining
|
||||
, gv$session_longops.opname
|
||||
, nvl(gv$session_longops.target,replace(gv$session_longops.target_desc,'Table ')) target
|
||||
, gv$session_longops.sid
|
||||
, gv$session_longops.inst_id
|
||||
, gv$session_longops.username
|
||||
, gv$session_longops.sql_hash_value
|
||||
from gv$session_longops
|
||||
, gv$session
|
||||
where gv$session_longops.sid = gv$session.sid
|
||||
and gv$session_longops.inst_id = gv$session.inst_id
|
||||
and gv$session_longops.sid = gv$session.sid
|
||||
and gv$session_longops.serial# = gv$session.serial#
|
||||
and gv$session_longops.time_remaining > 0
|
||||
and gv$session_longops.username = user
|
||||
) a
|
||||
,(select value from gv$parameter where name = 'db_block_size' and rownum = 1) b
|
||||
)
|
||||
select
|
||||
scan_data.inst_id
|
||||
, round(blocks_remaining*block_size/1024/1024/time_remaining,1) MB_per_Second
|
||||
, scan_data.time_remaining
|
||||
, round(time_remaining/(1-pct_scanned/100)) predicted_runtime_seconds
|
||||
, scan_data.pct_scanned
|
||||
, scan_data.blocks_remaining
|
||||
, round(blocks_remaining/(1-pct_scanned/100)) total_blocks
|
||||
, scan_data.opname
|
||||
, scan_data.BLOCK_SIZE
|
||||
, scan_data.target
|
||||
, (
|
||||
select
|
||||
max(operation_id)||':'||DECODE(MAX(NUMBER_PASSES),0,'OPTIMAL',1,'ONE-PASS',NULL,NULL,'MULTI-PASS('||max(number_passes)||')')||DECODE(max(TEMPSEG_SIZE),NULL,NULL,','||round(max(TEMPSEG_SIZE)/1024/1024)||'M')
|
||||
from gv$sql_workarea_active
|
||||
where gv$sql_workarea_active.sid = scan_data.sid
|
||||
and gv$sql_workarea_active.inst_id = scan_data.inst_id
|
||||
-- and scan_data.opname in ('Hash Join','Sort Output')
|
||||
-- and gv$sql_workarea_active.OPERATION_TYPE in ('HASH-JOIN','SORT','WINDOW (SORT)','GROUP BY (SORT)')
|
||||
) id_passes_temp
|
||||
, scan_data.sid
|
||||
, scan_data.username
|
||||
, scan_data.sql_hash_value
|
||||
from scan_data
|
||||
order by inst_id,username,sid,time_remaining
|
||||
/
|
||||
1
Kevin_Meade/showmyworkareas.sql
Normal file
1
Kevin_Meade/showmyworkareas.sql
Normal file
@@ -0,0 +1 @@
|
||||
select * from gv$sql_workarea_active where (inst_id,sid) in (select inst_id,sid from gv$session where username = user);
|
||||
12
Kevin_Meade/showowner.sql
Normal file
12
Kevin_Meade/showowner.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
--
|
||||
-- given an object name
|
||||
-- show what schema owns it and what it is
|
||||
--
|
||||
|
||||
col object_name format a30
|
||||
|
||||
select owner,object_type,object_name,status
|
||||
from dba_objects
|
||||
where object_name = upper('&&1')
|
||||
order by 1,2,3
|
||||
/
|
||||
35
Kevin_Meade/showparameters.sql
Normal file
35
Kevin_Meade/showparameters.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
col value format a30
|
||||
col name format a40
|
||||
col keyword format a10
|
||||
|
||||
break on keyword skip 1 dup
|
||||
|
||||
select decode(sign(instr(name,'dyn')),1,'dyn'
|
||||
,decode(sign(instr(name,'size')),1,'size'
|
||||
,decode(sign(instr(name,'pga')),1,'pga'
|
||||
,decode(sign(instr(name,'index')),1,'index'
|
||||
,decode(sign(instr(name,'cpu')),1,'cpu'
|
||||
,decode(sign(instr(name,'mode')),1,'mode'
|
||||
,decode(sign(instr(name,'optimizer')),1,'optimizer'
|
||||
,decode(sign(instr(name,'parallel')),1,'parallel'
|
||||
,decode(sign(instr(name,'rewrite')),1,'rewrite'
|
||||
,decode(sign(instr(name,'statistics')),1,'statistics'
|
||||
)))))))))) keyword
|
||||
,name
|
||||
,value
|
||||
,isdefault
|
||||
from v$parameter
|
||||
where (
|
||||
name like '%dyn%' or
|
||||
name like '%pga%' or
|
||||
name like '%area%' or
|
||||
name like '%index%' or
|
||||
name like '%cpu%' or
|
||||
name like '%mode%' or
|
||||
name like '%optimizer%' or
|
||||
name like 'parallel%' or
|
||||
name like '%rewrite%' or
|
||||
name like '%statistics%'
|
||||
)
|
||||
order by keyword,name
|
||||
/
|
||||
7
Kevin_Meade/showplan11g.sql
Normal file
7
Kevin_Meade/showplan11g.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
--
|
||||
-- dump the most recent plan from the plan_table
|
||||
--
|
||||
-- usage is: @SHOWPLAN11G
|
||||
--
|
||||
|
||||
select * from table(dbms_xplan.display('PLAN_TABLE',NULL,'ADVANCED'));
|
||||
8
Kevin_Meade/showplan11gshort.sql
Normal file
8
Kevin_Meade/showplan11gshort.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
--
|
||||
-- dump the most recent plan in the plan_table
|
||||
-- but do not include lesser used sections of the plan
|
||||
--
|
||||
-- usage is: @SHOWPLAN11GSHORT
|
||||
--
|
||||
|
||||
select * from table(dbms_xplan.display('PLAN_TABLE',NULL,'ADVANCED -projection -outline -alias'));
|
||||
60
Kevin_Meade/showplanconstraints11g.sql
Normal file
60
Kevin_Meade/showplanconstraints11g.sql
Normal file
@@ -0,0 +1,60 @@
|
||||
--
|
||||
-- show all PK/UK/FK constraints for any table referenced by most recent query plan in the plan_table
|
||||
-- note that table references may be indirect and that not all tables in a query need be used by a query plan
|
||||
--
|
||||
-- usage is: @SHOWPLANCONSTRAINTS11G
|
||||
--
|
||||
|
||||
break on constraint_name skip 1 on parent_table_name
|
||||
col column_name format a30
|
||||
col sort_order noprint
|
||||
col select_id noprint
|
||||
|
||||
with
|
||||
plan_references as (
|
||||
select id,object_owner owner,object_name table_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table
|
||||
where object_type = 'TABLE'
|
||||
and plan_id = (select max(plan_id) from plan_table)
|
||||
union
|
||||
select id,b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table a
|
||||
,dba_indexes b
|
||||
where a.object_type like 'INDEX%'
|
||||
and a.object_owner = b.owner
|
||||
and a.object_name = b.index_name
|
||||
and a.plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
, plan_tables as (
|
||||
select distinct owner,table_name
|
||||
from plan_references
|
||||
)
|
||||
select *
|
||||
from (
|
||||
select a.owner,a.table_name,a.constraint_name,a.constraint_type,c.column_name,b.owner parent_child_owner,b.table_name parent_child_table_name,b.constraint_type parent_constraint_type,a.index_name,decode(a.constraint_type,'P',1,'U',2) sort_order,1 select_id
|
||||
from dba_constraints a
|
||||
,dba_constraints b
|
||||
,dba_cons_columns c
|
||||
where (a.owner,a.table_name) in (select owner,table_name from plan_tables)
|
||||
and a.r_owner = b.owner(+)
|
||||
and a.r_constraint_name = b.constraint_name(+)
|
||||
and a.owner = c.owner
|
||||
and a.constraint_name = c.constraint_name
|
||||
and a.constraint_type != 'C'
|
||||
and (b.owner is null and a.constraint_type in ('P','U') or (b.owner,b.table_name) in (select owner,table_name from plan_tables))
|
||||
union
|
||||
select a.owner,a.table_name,a.constraint_name,a.constraint_type,c.column_name,b.owner parent_child_owner,b.table_name parent_child_table_name,b.constraint_type parent_constraint_type,a.index_name,decode(a.constraint_type,'P',1,'U',2) sort_order,2 select_id
|
||||
from dba_constraints a
|
||||
,dba_constraints b
|
||||
,dba_cons_columns c
|
||||
where (a.owner,a.table_name) in (select owner,table_name from plan_tables)
|
||||
and b.constraint_type in ('P','U')
|
||||
and a.r_owner = b.owner
|
||||
and a.r_constraint_name = b.constraint_name
|
||||
and b.table_name != a.table_name
|
||||
and a.owner = c.owner
|
||||
and a.constraint_name = c.constraint_name
|
||||
and (b.owner,b.table_name) in (select owner,table_name from plan_tables)
|
||||
)
|
||||
order by select_id,sort_order,owner,table_name,constraint_name,column_name
|
||||
/
|
||||
26
Kevin_Meade/showplancountqueries11g.sql
Normal file
26
Kevin_Meade/showplancountqueries11g.sql
Normal file
@@ -0,0 +1,26 @@
|
||||
--
|
||||
-- construct count queries for tables referenced by the most recent plan in the plan_table
|
||||
--
|
||||
-- usage is: @SHOWPLANCOUNTQUERIES11G
|
||||
--
|
||||
|
||||
select count_query_sqltext||decode(lead(count_query_sqltext) over (order by object_owner,object_name),null,';',' union all') sql_text
|
||||
from (
|
||||
select distinct object_owner,object_name,'select count(*) rowcount,'''||object_owner||''' owner,'''||object_name||''' table_name from '||object_owner||'.'||object_name count_query_sqltext
|
||||
from (
|
||||
select id,object_owner,object_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table
|
||||
where object_type = 'TABLE'
|
||||
and plan_id = (select max(plan_id) from plan_table)
|
||||
union
|
||||
select id,b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table a
|
||||
,dba_indexes b
|
||||
where a.object_type like 'INDEX%'
|
||||
and a.object_owner = b.owner
|
||||
and a.object_name = b.index_name
|
||||
and a.plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
order by object_owner,object_name
|
||||
)
|
||||
/
|
||||
209
Kevin_Meade/showplandatamodel11g.sql
Normal file
209
Kevin_Meade/showplandatamodel11g.sql
Normal file
@@ -0,0 +1,209 @@
|
||||
--
|
||||
-- dumps a crude ascii art data model for the current plan in the plan_table
|
||||
--
|
||||
-- usage is: @SHOWPLANDATAMODEL11G
|
||||
--
|
||||
|
||||
with
|
||||
table_list as (
|
||||
select b.*,chr(rownum+96) dm_key
|
||||
from (
|
||||
select a.*
|
||||
from (
|
||||
select object_owner owner,object_name table_name
|
||||
from plan_table
|
||||
where object_type = 'TABLE'
|
||||
and plan_id = (select max(plan_id) from plan_table)
|
||||
union
|
||||
select b.table_owner,b.table_name
|
||||
from plan_table a
|
||||
,dba_indexes b
|
||||
where a.object_type like 'INDEX%'
|
||||
and a.object_owner = b.owner
|
||||
and a.object_name = b.index_name
|
||||
and a.plan_id = (select max(plan_id) from plan_table)
|
||||
) a
|
||||
order by a.table_name,a.owner
|
||||
) b
|
||||
)
|
||||
, constraint_data as (
|
||||
select a.owner,a.table_name,a.constraint_type,a.constraint_name,a.r_owner,a.r_constraint_name
|
||||
,nvl(b.owner,a.owner) parent_owner,nvl(b.table_name,a.table_name) parent_table_name
|
||||
,decode(a.constraint_type,'R',a.owner) child_owner,decode(a.constraint_type,'R',a.table_name) child_table_name
|
||||
from dba_constraints a
|
||||
,dba_constraints b
|
||||
where a.constraint_type in ('P','R')
|
||||
and (a.owner,a.table_name) in (select owner,table_name from table_list)
|
||||
and a.r_owner = b.owner(+)
|
||||
and a.r_constraint_name = b.constraint_name(+)
|
||||
union all
|
||||
select owner,table_name,'P',null,null,null,null,null,null,null
|
||||
from table_list a
|
||||
where not exists (
|
||||
select null
|
||||
from dba_constraints b
|
||||
where b.owner = a.owner
|
||||
and b.table_name = a.table_name
|
||||
and b.constraint_type = 'P'
|
||||
)
|
||||
)
|
||||
, table_list_plus as (
|
||||
select a.owner,a.table_name,listagg(c.dm_key,',') within group (order by c.dm_key) parent_dm_key_list
|
||||
from table_list a
|
||||
,constraint_data b
|
||||
,table_list c
|
||||
where a.owner = b.child_owner
|
||||
and a.table_name = b.child_table_name
|
||||
and b.parent_owner = c.owner
|
||||
and b.parent_table_name = c.table_name
|
||||
group by a.owner,a.table_name
|
||||
)
|
||||
, table_level as (
|
||||
select c.*,(ordinal_position)*prefix_spaces+(ordinal_position-1)*3+cumm_table_name_length-length(table_name)+1 start_position
|
||||
from (
|
||||
select b.*,trunc((max_total_table_name_length-total_table_name_length)/(table_count+1)) prefix_spaces
|
||||
from (
|
||||
select a.*,max(table_count) over () max_table_count,max(total_table_name_length) over() max_total_table_name_length
|
||||
from (
|
||||
select owner,table_name,max(lvlno) dm_lvl,max_dm_lvl
|
||||
,sum(length(table_name)) over (partition by max(lvlno)) total_table_name_length
|
||||
,count(*) over(partition by max(lvlno)) table_count
|
||||
,row_number() over(partition by max(lvlno) order by table_name,owner) ordinal_position
|
||||
,sum(length(table_name)) over (partition by max(lvlno) order by table_name,owner) cumm_table_name_length
|
||||
from (
|
||||
select level lvlno,max(level) over () max_dm_lvl,a.*
|
||||
from constraint_data a
|
||||
connect by r_owner = prior owner
|
||||
and r_constraint_name = prior constraint_name
|
||||
start with r_owner is null
|
||||
)
|
||||
group by owner,table_name,max_dm_lvl
|
||||
) a
|
||||
) b
|
||||
) c
|
||||
)
|
||||
, table_lines as (
|
||||
select a.*
|
||||
from (
|
||||
select table_level.*,replace(substr(sys_connect_by_path(lpad(' ',prefix_spaces,' ')||table_name,','),2),',',' ') line_text
|
||||
from table_level
|
||||
connect by prior dm_lvl = dm_lvl
|
||||
and prior ordinal_position = ordinal_position - 1
|
||||
start with ordinal_position = 1
|
||||
) a
|
||||
where ordinal_position = table_count
|
||||
order by dm_lvl
|
||||
)
|
||||
, print_array as (
|
||||
select x.*
|
||||
,case
|
||||
when exists (
|
||||
select null
|
||||
from table_level b2
|
||||
,constraint_data c2
|
||||
,table_level d2
|
||||
where x.columnno = b2.start_position
|
||||
and b2.owner = c2.parent_owner
|
||||
and b2.table_name = c2.parent_table_name
|
||||
and c2.child_owner = d2.owner
|
||||
and c2.child_table_name = d2.table_name
|
||||
and (
|
||||
x.dm_lvl < d2.dm_lvl-1 or
|
||||
x.dm_lvl = d2.dm_lvl-1 and x.rowno in (1,2)
|
||||
)
|
||||
) then (
|
||||
select e2.dm_key
|
||||
from table_level b2
|
||||
,constraint_data c2
|
||||
,table_level d2
|
||||
,table_list e2
|
||||
where x.columnno = b2.start_position
|
||||
and b2.owner = c2.parent_owner
|
||||
and b2.table_name = c2.parent_table_name
|
||||
and c2.child_owner = d2.owner
|
||||
and c2.child_table_name = d2.table_name
|
||||
and (
|
||||
x.dm_lvl < d2.dm_lvl-1 or
|
||||
x.dm_lvl = d2.dm_lvl-1 and x.rowno in (1,2)
|
||||
)
|
||||
and c2.parent_owner = e2.owner
|
||||
and c2.parent_table_name = e2.table_name
|
||||
)
|
||||
when exists (
|
||||
select null
|
||||
from table_level b2
|
||||
,constraint_data c2
|
||||
,table_level d2
|
||||
where x.dm_lvl = b2.dm_lvl-1
|
||||
and x.rowno in (3)
|
||||
and b2.owner = c2.child_owner
|
||||
and b2.table_name = c2.child_table_name
|
||||
and c2.parent_owner = d2.owner
|
||||
and c2.parent_table_name = d2.table_name
|
||||
and (x.columnno between b2.start_position and d2.start_position or
|
||||
x.columnno between d2.start_position and b2.start_position)
|
||||
) then '-'
|
||||
when exists (
|
||||
select null
|
||||
from table_level b2
|
||||
,constraint_data c2
|
||||
where x.columnno = b2.start_position
|
||||
and b2.owner = c2.child_owner
|
||||
and b2.table_name = c2.child_table_name
|
||||
and x.dm_lvl = b2.dm_lvl-1
|
||||
and x.rowno in (4,5)
|
||||
) then (
|
||||
select decode(x.rowno,4,'|','| ('||f2.parent_dm_key_list||')')
|
||||
from table_level b2
|
||||
,constraint_data c2
|
||||
,table_list_plus f2
|
||||
where x.columnno = b2.start_position
|
||||
and b2.owner = c2.child_owner
|
||||
and b2.table_name = c2.child_table_name
|
||||
and x.dm_lvl = b2.dm_lvl-1
|
||||
and x.rowno in (4,5)
|
||||
and b2.owner = f2.owner
|
||||
and b2.table_name = f2.table_name
|
||||
)
|
||||
else ' '
|
||||
end cell_value
|
||||
from (
|
||||
select c.dm_lvl,2 rowtype,b.rowno,a.rowno columnno
|
||||
from (
|
||||
select rownum rowno
|
||||
from dual
|
||||
connect by level <= (select max(length(line_text)) from table_lines)
|
||||
) a
|
||||
,(
|
||||
select level rowno
|
||||
from dual
|
||||
connect by level <= 5
|
||||
) b
|
||||
,table_lines c
|
||||
where c.dm_lvl < c.max_dm_lvl
|
||||
and a.rowno <= length(c.line_text)
|
||||
) x
|
||||
)
|
||||
, constraint_lines as (
|
||||
select *
|
||||
from (
|
||||
select dm_lvl,rowtype,rowno,columnno,connect_by_isleaf cbil,replace(sys_connect_by_path(cell_value,','),',') line_text
|
||||
from print_array
|
||||
connect by prior dm_lvl = dm_lvl
|
||||
and prior rowtype = rowtype
|
||||
and prior rowno = rowno
|
||||
and prior columnno = columnno-1
|
||||
start with columnno = 1
|
||||
)
|
||||
where cbil = 1
|
||||
)
|
||||
, data_model as (
|
||||
select dm_lvl,1 rowtype,1 rowno,line_text
|
||||
from table_lines
|
||||
union all
|
||||
select dm_lvl,rowtype,rowno,line_text
|
||||
from constraint_lines
|
||||
order by 1,2,3
|
||||
)
|
||||
select ' '||line_text data_model from data_model
|
||||
/
|
||||
36
Kevin_Meade/showplandrivingtable11g.sql
Normal file
36
Kevin_Meade/showplandrivingtable11g.sql
Normal file
@@ -0,0 +1,36 @@
|
||||
--
|
||||
-- show the driving table for the most recent query plan in the plan_table
|
||||
--
|
||||
-- usage is: @SHOWPLANDRIVINGTABLES11G
|
||||
--
|
||||
|
||||
set linesize 999
|
||||
col driving_table format a61
|
||||
col driving_table_alias format a30
|
||||
col leading_hint format a300
|
||||
|
||||
|
||||
select id
|
||||
,object_owner||'.'||object_name driving_table
|
||||
,driving_table_alias
|
||||
,object_type
|
||||
,leading_hint
|
||||
from (
|
||||
select substr(replace(leading_hint,')',' ')
|
||||
,instr(replace(leading_hint,')',' '),' ',1,1)+1
|
||||
,instr(replace(leading_hint,')',' '),' ',1,2)-instr(replace(leading_hint,')',' '),' ',1,1)-1) driving_table_alias
|
||||
,leading_hint
|
||||
from (
|
||||
select substr(c1,1,instr(c1,')')) leading_hint
|
||||
from (
|
||||
select substr(other_xml,instr(other_xml,'LEADING(')) c1
|
||||
from plan_table
|
||||
where other_xml is not null
|
||||
and plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
)
|
||||
) x
|
||||
,plan_table
|
||||
where plan_table.object_alias = trim(replace(to_char(substr(x.driving_table_alias,1,4000)),'"'))
|
||||
and plan_table.plan_id = (select max(plan_id) from plan_table)
|
||||
/
|
||||
103
Kevin_Meade/showplanfilterqueries11g.sql
Normal file
103
Kevin_Meade/showplanfilterqueries11g.sql
Normal file
@@ -0,0 +1,103 @@
|
||||
--
|
||||
-- show filter queries for the most recent plan in the plan_table
|
||||
--
|
||||
-- usage is: @SHOWPLANFILTERQUERIES11G
|
||||
--
|
||||
|
||||
with
|
||||
table_list as (
|
||||
select 'TABLE' plan_object_type,a.id,a.object_owner table_owner,a.object_name table_name,a.access_predicates,a.filter_predicates,a.object_alias,a.cardinality
|
||||
from plan_table a
|
||||
,dba_tables b
|
||||
where b.owner = a.object_owner
|
||||
and b.table_name = a.object_name
|
||||
and a.plan_id = (select max(plan_id) from plan_table)
|
||||
union all
|
||||
select 'INDEX' plan_object_type,a.id,b.table_owner,b.table_name object_name,a.access_predicates,a.filter_predicates,a.object_alias,a.cardinality
|
||||
from plan_table a
|
||||
,dba_indexes b
|
||||
where b.owner = a.object_owner
|
||||
and b.index_name = a.object_name
|
||||
and a.plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
--
|
||||
-- given the raw data for tables, modify the predicates so that we only see predicates for constant tests, no join predicates
|
||||
-- join predicates are not used in FRP analysis
|
||||
-- this is a bit of a hack as I never took the COMPILER and PARSER classes in school, basically this means it is almost 100%right
|
||||
--
|
||||
, modified_table_list as (
|
||||
select id,table_owner,table_name,object_alias,cardinality,plan_object_type
|
||||
,case when
|
||||
instr(replace(access_predicates,'"="'),'=') > 0 or
|
||||
instr(replace(access_predicates,'">"'),'>') > 0 or
|
||||
instr(replace(access_predicates,'"<"'),'<') > 0 or
|
||||
instr(replace(access_predicates,'">="'),'>=') > 0 or
|
||||
instr(replace(access_predicates,'"<="'),'<=') > 0 or
|
||||
instr(replace(access_predicates,'"!="'),'!=') > 0 or
|
||||
instr(replace(access_predicates,'"<>"'),'<>') > 0 or
|
||||
instr(replace(access_predicates,'" LIKE "'),' LIKE ') > 0 or
|
||||
instr(replace(access_predicates,'" BETWEEN "'),' BETWEEN ') > 0 or
|
||||
instr(replace(access_predicates,'" IN ("'),' IN (') > 0 or
|
||||
instr(replace(access_predicates,'" NOT LIKE "'),' NOT LIKE ') > 0 or
|
||||
instr(replace(access_predicates,'" NOT BETWEEN "'),' NOT BETWEEN ') > 0 or
|
||||
instr(replace(access_predicates,'" NOT IN ("'),' NOT IN (') > 0
|
||||
then access_predicates
|
||||
end access_predicates
|
||||
,case when
|
||||
instr(replace(filter_predicates,'"="'),'=') > 0 or
|
||||
instr(replace(filter_predicates,'">"'),'>') > 0 or
|
||||
instr(replace(filter_predicates,'"<"'),'<') > 0 or
|
||||
instr(replace(filter_predicates,'">="'),'>=') > 0 or
|
||||
instr(replace(filter_predicates,'"<="'),'<=') > 0 or
|
||||
instr(replace(filter_predicates,'"!="'),'!=') > 0 or
|
||||
instr(replace(filter_predicates,'"<>"'),'<>') > 0 or
|
||||
instr(replace(filter_predicates,'" LIKE "'),' LIKE ') > 0 or
|
||||
instr(replace(filter_predicates,'" BETWEEN "'),' BETWEEN ') > 0 or
|
||||
instr(replace(filter_predicates,'" IN ("'),' IN (') > 0 or
|
||||
instr(replace(filter_predicates,'" NOT LIKE "'),' NOT LIKE ') > 0 or
|
||||
instr(replace(filter_predicates,'" NOT BETWEEN "'),' NOT BETWEEN ') > 0 or
|
||||
instr(replace(filter_predicates,'" NOT IN ("'),' NOT IN (') > 0
|
||||
then filter_predicates
|
||||
end filter_predicates
|
||||
from table_list
|
||||
)
|
||||
--
|
||||
-- do the final massaging of the raw data
|
||||
-- in particular, get the true alias for each table, get data from dba_tables, generate an actual predicate we can test with
|
||||
--
|
||||
, plan_info as
|
||||
(
|
||||
select
|
||||
id
|
||||
, table_owner
|
||||
, table_name
|
||||
, substr(object_alias,1,instr(object_alias,'@')-1) table_alias
|
||||
, cardinality
|
||||
, (select num_rows from dba_tables where dba_tables.owner = modified_table_list.table_owner and dba_tables.table_name = modified_table_list.table_name) num_rows
|
||||
, case
|
||||
when access_predicates is null and filter_predicates is null then null
|
||||
when access_predicates is null and filter_predicates is not null then filter_predicates
|
||||
when access_predicates is not null and filter_predicates is null then access_predicates
|
||||
when access_predicates is not null and filter_predicates is not null and access_predicates != filter_predicates then access_predicates||' and '||filter_predicates
|
||||
else access_predicates
|
||||
end predicate
|
||||
from modified_table_list
|
||||
)
|
||||
--
|
||||
-- look for places where indexes are accessed followed by table acces by rowid
|
||||
-- combine the two lines into one
|
||||
--
|
||||
, combined_plan_info as (
|
||||
select plan_info.table_owner,plan_info.table_name,plan_info.table_alias,plan_info.num_rows
|
||||
,min(plan_info.id) id
|
||||
,max(plan_info.cardinality) cardinality
|
||||
,listagg(plan_info.predicate,' and ') within group (order by id) predicate
|
||||
from plan_info
|
||||
group by plan_info.table_owner,plan_info.table_name,plan_info.table_alias,plan_info.num_rows
|
||||
)
|
||||
select 'select count(*) filtered_rowcount,'''||table_owner||''' table_owner,'''||table_name||''' table_name,'''||table_alias||''' table_alias from '||table_owner||'.'||table_name||' '||table_alias||decode(predicate,null,null,' where '||predicate)
|
||||
||decode(lead(table_name) over (order by table_owner,table_name),null,' ;',' union all')
|
||||
from combined_plan_info
|
||||
order by table_owner,table_name
|
||||
/
|
||||
|
||||
141
Kevin_Meade/showplanfrpspreadsheetcode11g.sql
Normal file
141
Kevin_Meade/showplanfrpspreadsheetcode11g.sql
Normal file
@@ -0,0 +1,141 @@
|
||||
--
|
||||
-- generate SQL for the FRP spreadsheet from the most recent plan in the plan_table
|
||||
--
|
||||
-- usage is: @SHOWPLANFRPSPREADSHEETCODE11G
|
||||
--
|
||||
|
||||
col actual_frp format 999.0
|
||||
col plan_frp format 999.0
|
||||
col select_id noprint
|
||||
|
||||
with
|
||||
--
|
||||
-- generates a FRP SPREADSHEET query using plan table information for an EXPLAINED query
|
||||
--
|
||||
--
|
||||
-- THIS CODE IS DEPENDENT UPON WHAT IS IN THE PLAN TABLE
|
||||
-- among other things this means that if oracle changes the contents of this table, this query may stop working
|
||||
--
|
||||
-- several possible flaws can prevent this code from generating an executable SQL SELECT
|
||||
--
|
||||
-- 1. bind variables: the corresponding select here must be modified to group on the bind column and select an round(avg(count(*))
|
||||
-- 2. join predicates: if any are used along with constant tests in a plan step, they must be manaully edited out of the correspoding select here
|
||||
-- 3. packaged functions: column=functioncall predicates can be dropped in which case filtered_cardinality will be affected, check it if you query has these
|
||||
-- 4. outer join is not supported. These should be removed. If the case expression becomes empty use count(*).
|
||||
-- 5. correlated subqueries are confusing. This is because the appear as queries with bind variables. Test like #1 but ingnore their results.
|
||||
--
|
||||
--
|
||||
-- get raw_data from the plan_table for each table reference in the query plan
|
||||
-- a table may be used more than once in which case there will be more than one row returned here
|
||||
-- this is managed by using ID so that we know the plan step the table reference refers to
|
||||
-- note that some plan steps may be index lookups so in this section we translate the index to its underlying table
|
||||
--
|
||||
table_list as (
|
||||
select a.id,a.object_owner table_owner,a.object_name table_name,a.access_predicates,a.filter_predicates,a.object_alias,a.cardinality
|
||||
from plan_table a
|
||||
,dba_tables b
|
||||
where b.owner = a.object_owner
|
||||
and b.table_name = a.object_name
|
||||
and a.plan_id = (select max(plan_id) from plan_table)
|
||||
union all
|
||||
select a.id,b.table_owner,b.table_name object_name,a.access_predicates,a.filter_predicates,a.object_alias,a.cardinality
|
||||
from plan_table a
|
||||
,dba_indexes b
|
||||
where b.owner = a.object_owner
|
||||
and b.index_name = a.object_name
|
||||
and a.plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
--
|
||||
-- given the raw data for tables, modify the predicates so that we only see predicates for constant tests, no join predicates
|
||||
-- join predicates are not used in FRP analysis
|
||||
-- this is a bit of a hack as I never took the COMPILER and PARSER classes in school, basically this means it is almost 100%right
|
||||
-- what we call "close enough for jazz"
|
||||
--
|
||||
, modified_table_list as (
|
||||
select id,table_owner,table_name,object_alias,cardinality
|
||||
,case when
|
||||
instr(replace(access_predicates,'"="'),'=') > 0 or
|
||||
instr(replace(access_predicates,'">"'),'>') > 0 or
|
||||
instr(replace(access_predicates,'"<"'),'<') > 0 or
|
||||
instr(replace(access_predicates,'">="'),'>=') > 0 or
|
||||
instr(replace(access_predicates,'"<="'),'<=') > 0 or
|
||||
instr(replace(access_predicates,'"!="'),'!=') > 0 or
|
||||
instr(replace(access_predicates,'"<>"'),'<>') > 0 or
|
||||
instr(replace(access_predicates,'" LIKE "'),' LIKE ') > 0 or
|
||||
instr(replace(access_predicates,'" BETWEEN "'),' BETWEEN ') > 0 or
|
||||
instr(replace(access_predicates,'" IN ("'),' IN (') > 0 or
|
||||
instr(replace(access_predicates,'" NOT LIKE "'),' NOT LIKE ') > 0 or
|
||||
instr(replace(access_predicates,'" NOT BETWEEN "'),' NOT BETWEEN ') > 0 or
|
||||
instr(replace(access_predicates,'" NOT IN ("'),' NOT IN (') > 0
|
||||
then access_predicates
|
||||
end access_predicates
|
||||
,case when
|
||||
instr(replace(filter_predicates,'"="'),'=') > 0 or
|
||||
instr(replace(filter_predicates,'">"'),'>') > 0 or
|
||||
instr(replace(filter_predicates,'"<"'),'<') > 0 or
|
||||
instr(replace(filter_predicates,'">="'),'>=') > 0 or
|
||||
instr(replace(filter_predicates,'"<="'),'<=') > 0 or
|
||||
instr(replace(filter_predicates,'"!="'),'!=') > 0 or
|
||||
instr(replace(filter_predicates,'"<>"'),'<>') > 0 or
|
||||
instr(replace(filter_predicates,'" LIKE "'),' LIKE ') > 0 or
|
||||
instr(replace(filter_predicates,'" BETWEEN "'),' BETWEEN ') > 0 or
|
||||
instr(replace(filter_predicates,'" IN ("'),' IN (') > 0 or
|
||||
instr(replace(filter_predicates,'" NOT LIKE "'),' NOT LIKE ') > 0 or
|
||||
instr(replace(filter_predicates,'" NOT BETWEEN "'),' NOT BETWEEN ') > 0 or
|
||||
instr(replace(filter_predicates,'" NOT IN ("'),' NOT IN (') > 0
|
||||
then filter_predicates
|
||||
end filter_predicates
|
||||
from table_list
|
||||
)
|
||||
--
|
||||
-- do the final massaging of the raw data
|
||||
-- in particular, get the true alias for each table, get data from dba_tables, generate an actual predicate we can test with
|
||||
--
|
||||
, plan_info as
|
||||
(
|
||||
select
|
||||
id
|
||||
, table_owner
|
||||
, table_name
|
||||
, substr(object_alias,1,instr(object_alias,'@')-1) table_alias
|
||||
, cardinality
|
||||
, (select num_rows from dba_tables where dba_tables.owner = modified_table_list.table_owner and dba_tables.table_name = modified_table_list.table_name) num_rows
|
||||
, case
|
||||
when access_predicates is null and filter_predicates is null then null
|
||||
when access_predicates is null and filter_predicates is not null then filter_predicates
|
||||
when access_predicates is not null and filter_predicates is null then access_predicates
|
||||
when access_predicates is not null and filter_predicates is not null and access_predicates != filter_predicates then access_predicates||' and '||filter_predicates
|
||||
else access_predicates
|
||||
end predicate
|
||||
from modified_table_list
|
||||
)
|
||||
--
|
||||
-- look for places where indexes are accessed followed by table acces by rowid
|
||||
-- combine the two lines into one
|
||||
--
|
||||
, combined_plan_info as (
|
||||
select plan_info.table_owner,plan_info.table_name,plan_info.table_alias,plan_info.cardinality,plan_info.num_rows
|
||||
,min(plan_info.id) id
|
||||
,listagg(plan_info.predicate,' and ') within group (order by id) predicate
|
||||
from plan_info
|
||||
group by plan_info.table_owner,plan_info.table_name,plan_info.table_alias,plan_info.cardinality,plan_info.num_rows
|
||||
)
|
||||
--
|
||||
-- give us a SQL statement that for each table reference, both counts all rows and counts only rows that pass the filter predictes
|
||||
-- then do the math needed to generate an FRP SPREADSHEET
|
||||
-- this version (4) only scans each table once instead of twice like the old versions
|
||||
--
|
||||
select 1 select_id,'with' sqltext from dual union all
|
||||
select 2 select_id,' frp_data as (' from dual union all
|
||||
select 3 select_id,' select '''||lpad(id,5,' ')||''' id,'''||table_owner||''' table_owner,'''||table_name||''' table_name,'''||table_alias||''' table_alias,'||nvl(to_char(num_rows),'cast(null as number)')||' num_rows,count(*) rowcount,'||cardinality||' cardinality,'||decode(predicate,null,'cast(null as number)','count(case when '||predicate||' then 1 end)')||' filtered_cardinality from '||table_owner||'.'||table_name||' '||table_alias||' union all'
|
||||
from combined_plan_info
|
||||
union all
|
||||
select 4 select_id,' select null,null,null,null,null,null,null,null from dual' from dual union all
|
||||
select 5 select_id,' )' from dual union all
|
||||
select 6 select_id,'select frp_data.*,round(frp_data.filtered_cardinality/case when frp_data.rowcount = 0 then cast(null as number) else frp_data.rowcount end*100,1) actual_frp,decode(frp_data.filtered_cardinality,null,cast(null as number),round(frp_data.cardinality/case when frp_data.num_rows = 0 then cast(null as number) else frp_data.num_rows end*100,1)) plan_frp' from dual union all
|
||||
select 7 select_id,'from frp_data' from dual union all
|
||||
select 8 select_id,'where id is not null' from dual union all
|
||||
select 9 select_id,'order by frp_data.id' from dual union all
|
||||
select 10 select_id,'/' from dual
|
||||
order by 1
|
||||
/
|
||||
38
Kevin_Meade/showplanindexes11g.sql
Normal file
38
Kevin_Meade/showplanindexes11g.sql
Normal file
@@ -0,0 +1,38 @@
|
||||
--
|
||||
-- show indexes for any table referenced directly or indirectly in the current plan of the plan_table
|
||||
--
|
||||
-- usage is: @SHOWPLANINDEXES11G
|
||||
--
|
||||
|
||||
break on table_owner on table_name on index_owner skip 1 on index_name skip 1 on uniqueness
|
||||
col column_name format a30
|
||||
|
||||
with
|
||||
plan_references as (
|
||||
select id,object_owner owner,object_name table_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table
|
||||
where object_type = 'TABLE'
|
||||
and plan_id = (select max(plan_id) from plan_table)
|
||||
union
|
||||
select id,b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table a
|
||||
,dba_indexes b
|
||||
where a.object_type like 'INDEX%'
|
||||
and a.object_owner = b.owner
|
||||
and a.object_name = b.index_name
|
||||
and a.plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
, plan_tables as (
|
||||
select distinct owner,table_name
|
||||
from plan_references
|
||||
)
|
||||
select dba_ind_columns.column_name,dba_indexes.index_name,dba_indexes.uniqueness,dba_indexes.table_name,dba_indexes.table_owner,dba_indexes.owner index_owner
|
||||
from dba_indexes
|
||||
,dba_ind_columns
|
||||
,plan_tables
|
||||
where plan_tables.owner = dba_indexes.table_owner
|
||||
and plan_tables.table_name = dba_indexes.table_name
|
||||
and dba_indexes.owner = dba_ind_columns.index_owner
|
||||
and dba_indexes.index_name = dba_ind_columns.index_name
|
||||
order by dba_indexes.table_owner,dba_indexes.table_name,dba_indexes.owner,dba_indexes.index_name,dba_ind_columns.column_position
|
||||
/
|
||||
28
Kevin_Meade/showplannumrows11g.sql
Normal file
28
Kevin_Meade/showplannumrows11g.sql
Normal file
@@ -0,0 +1,28 @@
|
||||
--
|
||||
-- get num_rows off DBA_TABLES for any table referenced by the current plan in the plan_table
|
||||
--
|
||||
-- usage is: @SHOWPLANNUMROWS11G
|
||||
--
|
||||
|
||||
with
|
||||
table_list as (
|
||||
select object_owner owner,object_name table_name
|
||||
from plan_table
|
||||
where object_type = 'TABLE'
|
||||
and plan_id = (select max(plan_id) from plan_table)
|
||||
union
|
||||
select b.table_owner,b.table_name
|
||||
from plan_table a
|
||||
,dba_indexes b
|
||||
where a.object_type like 'INDEX%'
|
||||
and a.object_owner = b.owner
|
||||
and a.object_name = b.index_name
|
||||
and a.plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
select num_rows,dba_tables.owner,dba_tables.table_name
|
||||
from dba_tables
|
||||
,table_list
|
||||
where table_list.owner = dba_tables.owner
|
||||
and table_list.table_name = dba_tables.table_name
|
||||
order by 2,1
|
||||
/
|
||||
128
Kevin_Meade/showplanquerydiagram11g.sql
Normal file
128
Kevin_Meade/showplanquerydiagram11g.sql
Normal file
@@ -0,0 +1,128 @@
|
||||
--
|
||||
-- show a query diagram for the current plan of the plan_table
|
||||
-- uses the join tree with extended information
|
||||
--
|
||||
-- usage is: @SHOWPLANQUERYDIAGRAM11G
|
||||
--
|
||||
|
||||
col query_diagram format a300
|
||||
col query_name format a30
|
||||
break on query_name skip 1 dup
|
||||
|
||||
with
|
||||
plan_table_current as (
|
||||
select *
|
||||
from plan_table
|
||||
where plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
, predicate_data as (
|
||||
select nvl(query_name,'SEL$1') adjusted_query_name
|
||||
,z.*
|
||||
from (
|
||||
select case
|
||||
when table_2_alias is null then 'CONSTANT TEST'
|
||||
else 'JOIN'
|
||||
end expression_type
|
||||
,substr(pt.object_alias,instr(object_alias,'@')+1) query_name
|
||||
,y.*
|
||||
from plan_table_current pt
|
||||
,(
|
||||
select case
|
||||
when instr(predicate_expression,'.') > 0 then substr(predicate_expression,1,instr(predicate_expression,'.')-1)
|
||||
else (select substr(object_alias,1,instr(object_alias,'@')-1) from plan_table_current where id = x.id and rownum = 1)
|
||||
end table_1_alias
|
||||
,substr(predicate_expression,instr(predicate_expression,'=')+1,instr(predicate_expression,'.',1,2)-instr(predicate_expression,'=')-1) table_2_alias
|
||||
,x.*
|
||||
from (
|
||||
select distinct *
|
||||
from (
|
||||
select id,substr( ' '||p||' '
|
||||
,instr(' '||p||' ',' ',1,level)+1
|
||||
,instr(' '||p||' ',' ',1,level+1)-instr(' '||p||' ',' ',1,level)-1
|
||||
) predicate_expression
|
||||
,level rowno
|
||||
,p
|
||||
from (
|
||||
select *
|
||||
from (
|
||||
select id,trim(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
p
|
||||
,' ',' ')
|
||||
,' ',' ')
|
||||
,' ',' ')
|
||||
,' ',' ')
|
||||
,' ',' ')
|
||||
,' ',' ')
|
||||
,' ',' ')
|
||||
,' ',' ')
|
||||
) p
|
||||
from (
|
||||
select id,trim(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
replace(
|
||||
p
|
||||
,'"')
|
||||
,' AND ',' ')
|
||||
,' OR ',' ')
|
||||
,' NOT ',' ')
|
||||
,'(',' ')
|
||||
,')',' ')
|
||||
,' and ',' ')
|
||||
,' and ',' ')
|
||||
) p
|
||||
from (
|
||||
select id,access_predicates||' '||filter_predicates p
|
||||
from plan_table_current
|
||||
where rownum >= 1
|
||||
)
|
||||
)
|
||||
)
|
||||
where p is not null
|
||||
)
|
||||
connect by level <= length(p)-length(replace(p,' '))+1
|
||||
)
|
||||
) x
|
||||
) y
|
||||
where y.id = pt.id
|
||||
) z
|
||||
)
|
||||
, constant_test as (
|
||||
select distinct expression_type,table_1_alias
|
||||
from predicate_data
|
||||
where expression_type = 'CONSTANT TEST'
|
||||
)
|
||||
select t.query_name
|
||||
,decode(ct,'c','c',' ')||lpad(decode(ct,'c','-',' '),(lvlno)*3,decode(ct,'c','-',' '))||table_2_alias query_diagram
|
||||
from (
|
||||
select query_name,table_1_alias,table_2_alias
|
||||
,level lvlno
|
||||
,max(level) over (partition by query_name) max_lvlno
|
||||
,case when (select expression_type from constant_test where table_1_alias = x.table_2_alias) is not null then 'c' end ct
|
||||
from (
|
||||
select distinct adjusted_query_name query_name,table_1_alias,table_2_alias
|
||||
from predicate_data
|
||||
where expression_type = 'JOIN'
|
||||
union all
|
||||
select distinct adjusted_query_name query_name,null,table_1_alias
|
||||
from predicate_data
|
||||
where table_1_alias not in (select table_2_alias from predicate_data where table_2_alias is not null)
|
||||
) x
|
||||
connect by prior table_2_alias = table_1_alias
|
||||
and prior query_name = query_name
|
||||
start with table_1_alias is null
|
||||
) t
|
||||
/
|
||||
23
Kevin_Meade/showplantables11g.sql
Normal file
23
Kevin_Meade/showplantables11g.sql
Normal file
@@ -0,0 +1,23 @@
|
||||
--
|
||||
-- show all tables referenced by the qep
|
||||
-- this include indrect references so an index reference translates to the table in this report
|
||||
--
|
||||
|
||||
with
|
||||
plan_table_current as (
|
||||
select *
|
||||
from plan_table
|
||||
where plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
select id,object_owner,object_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table_current
|
||||
where object_type = 'TABLE'
|
||||
union
|
||||
select id,b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table_current a
|
||||
,dba_indexes b
|
||||
where a.object_type like 'INDEX%'
|
||||
and a.object_owner = b.owner
|
||||
and a.object_name = b.index_name
|
||||
order by 2,3,1
|
||||
/
|
||||
22
Kevin_Meade/showplantablesunique11g.sql
Normal file
22
Kevin_Meade/showplantablesunique11g.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
--
|
||||
-- show actual unique list of tables referenced by the QEP
|
||||
--
|
||||
|
||||
with
|
||||
plan_table_current as (
|
||||
select *
|
||||
from plan_table
|
||||
where plan_id = (select max(plan_id) from plan_table)
|
||||
)
|
||||
select object_owner,object_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table_current
|
||||
where object_type = 'TABLE'
|
||||
union
|
||||
select b.table_owner,b.table_name,replace(object_alias,'@',' @ ') object_alias
|
||||
from plan_table_current a
|
||||
,dba_indexes b
|
||||
where a.object_type like 'INDEX%'
|
||||
and a.object_owner = b.owner
|
||||
and a.object_name = b.index_name
|
||||
order by 1,2
|
||||
/
|
||||
124
Kevin_Meade/showtopcpu11g.sql
Normal file
124
Kevin_Meade/showtopcpu11g.sql
Normal file
@@ -0,0 +1,124 @@
|
||||
--
|
||||
-- create a multi-part report on database SQL by instance
|
||||
-- grouping SQL into powers of ten based on cpu consumed
|
||||
-- in order to see easily the top 1% of queries that are most busy
|
||||
--
|
||||
|
||||
set linesize 999
|
||||
set pagesize 50000
|
||||
set feedback 1
|
||||
set trimspool on
|
||||
set trimout on
|
||||
set doc off
|
||||
clear breaks
|
||||
clear computes
|
||||
set echo off
|
||||
|
||||
-- alter session set nls_date_format = 'dd-mon-rrrr hh24:mi:ss';
|
||||
|
||||
select * from v$version
|
||||
/
|
||||
|
||||
select inst_id
|
||||
,instance_name
|
||||
,startup_time
|
||||
,round((sysdate-startup_time),1) up_days
|
||||
,round(round((sysdate-startup_time),1)*24) maximum_cache_hours
|
||||
,to_char(sysdate,'dd-mon-rrrr hh24:mi:ss') right_now
|
||||
from gv$instance
|
||||
order by inst_id
|
||||
/
|
||||
|
||||
--
|
||||
-- show how long the database has been up, how many cpus are available, and thus the theoretical CPU available
|
||||
--
|
||||
select inst_id
|
||||
,instance_name
|
||||
,(select cpu_count_highwater from sys.v_$license) cpu_count
|
||||
,round((round((sysdate-startup_time),1)*24)*(select cpu_count_highwater from sys.v_$license)) available_cpu_hours
|
||||
from gv$instance
|
||||
order by inst_id
|
||||
/
|
||||
|
||||
col sql_text format a700 trunc
|
||||
col sql_text clear
|
||||
col sql_text format a700 trunc
|
||||
col pct_total format 990
|
||||
compute sum of sql_statements on inst_id
|
||||
compute sum of sql_statements on report
|
||||
compute sum of db_pct_total on inst_id
|
||||
compute sum of db_pct_total on report
|
||||
compute sum of running_consumed_cpu_hours on report
|
||||
break on inst_id skip page on report
|
||||
|
||||
--
|
||||
-- use a logarithmic scale to plot cpu consumtion of all queries in the cache
|
||||
-- we can use this to zero in on the top consumers
|
||||
-- notice we exclude PLSQL CALLS but not the sql inside these calls
|
||||
-- this gives us the true SQL workload
|
||||
--
|
||||
select
|
||||
inst_id
|
||||
,cpu_time_log10
|
||||
,sql_statements
|
||||
,cpu_time_rounded,round(cpu_time) cpu_time
|
||||
,round(100*ratio_to_report(cpu_time) over(partition by inst_id)) inst_pct_total
|
||||
,round(100*ratio_to_report(cpu_time) over()) db_pct_total
|
||||
,round(sum(cpu_time) over (partition by inst_id order by cpu_time_log10)) running_cpu_time
|
||||
,round(round(sum(cpu_time) over (partition by inst_id order by cpu_time_log10))/60/60,2) running_consumed_cpu_hours
|
||||
from (
|
||||
select
|
||||
inst_id
|
||||
,trunc(log(10,mycpu_time)) cpu_time_log10
|
||||
,count(*) sql_statements
|
||||
,power(10,trunc(log(10,mycpu_time))) cpu_time_rounded
|
||||
,sum(mycpu_time) cpu_time
|
||||
from (
|
||||
select inst_id,case when cpu_time <= 0 then 1 else cpu_time end/1000000 mycpu_time
|
||||
from gv$sqlarea
|
||||
where trim(upper(sql_text)) not like 'BEGIN%'
|
||||
and trim(upper(sql_text)) not like 'DECLARE%'
|
||||
and trim(upper(sql_text)) not like 'CALL%'
|
||||
)
|
||||
group by trunc(log(10,mycpu_time)),inst_id
|
||||
) a
|
||||
order by inst_id,a.cpu_time_log10
|
||||
/
|
||||
|
||||
clear computes
|
||||
col module format a30 word
|
||||
col sec_per_exec format 999999990.0
|
||||
--compute sum of cpu_seconds on inst_id , report
|
||||
break on inst_id skip page
|
||||
--
|
||||
-- show use the actual SQL that exceeds some threshhold
|
||||
-- these are the queries we want to concentrate on
|
||||
-- configure the last AND predicate to whatever is reasonable based on the above query
|
||||
--
|
||||
select inst_id
|
||||
,sql_id
|
||||
,child_number
|
||||
,trunc(cpu_time/1000000) cpu_seconds
|
||||
,trunc(elapsed_time/1000000) eplapsed_seconds
|
||||
,executions
|
||||
,round(trunc(elapsed_time/1000000)/decode(executions,0,null,executions),1) sec_per_exec
|
||||
,round((sysdate-to_date(first_load_time,'rrrr-mm-dd/hh24:mi:ss'))*24) hours_in_cache
|
||||
,module
|
||||
-- ,address
|
||||
,hash_value
|
||||
,(select 'Open' from gv$open_cursor b where b.inst_id = a.inst_id and b.address = a.address and b.hash_value = a.hash_value and rownum = 1) open
|
||||
/*
|
||||
,case when sql_text like '%SELECT /*+ ORDERED NO_EXPAND USE_HASH%' or sql_text like '%FROM :Q%' or instr(sql_text,'CIV_GB') > 0 or instr(sql_text,'PIV_GB') > 0 or instr(sql_text,'PIV_SSF') > 0 or instr(sql_text,'SWAP_JOIN_INPUTS') > 0 then 'Slave'
|
||||
when sql_text like '%SELECT /*+ Q%' then 'Query'
|
||||
else (select 'Yes' from gv$sql_plan b where b.inst_id = a.inst_id and b.address = a.address and b.hash_value = a.hash_value and b.child_number = a.child_number and b.other_tag like 'PARALLEL%' and rownum = 1)
|
||||
end parallel
|
||||
*/
|
||||
,sql_text
|
||||
from gv$sql a
|
||||
where trim(upper(sql_text)) not like 'BEGIN%'
|
||||
and trim(upper(sql_text)) not like 'DECLARE%'
|
||||
and trim(upper(sql_text)) not like 'CALL%'
|
||||
and cpu_time/1000000 >= 1000
|
||||
--and cpu_time/1000000 >= 100
|
||||
order by 1,4,5
|
||||
/
|
||||
Reference in New Issue
Block a user