Last active
November 15, 2024 13:46
-
-
Save haballan/19f8af9efc8edf6c56ba9e63261ffe35 to your computer and use it in GitHub Desktop.
Script to tune a SQL Statement using DB Features. Complete Instructions in this link: http://dba-tips.blogspot.com/2020/10/sql-tuning-script.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ######################################################################################################################################## | |
# Retrieve the SQLTEXT + BIND VARIABLES + EXEC PLAN + PLAN HISTORY + BASELINE + FIX PLAN + TUNING ADVISOR | |
VER="[3.6]" | |
# # # # | |
# Authors: Mahmmoud ADEL # # # # # # | |
# Farrukh Salman # # # #### | |
# Created: 24-12-11 # # # # # | |
# Modified: 31-12-13 Customized the script to run on various environments. | |
# 06-05-14 Getting the Bind Variable info for the SQLID | |
# 05-11-15 Fix Divided by Zero error | |
# 16-06-16 Added SQL Tuning Option | |
# 26-02-17 Added Execution History quoted from sqlhistory.sql written by: Tim Gorman (Evergreen Database Technologies, Inc.) | |
# 14-11-17 Added a check for available tuning tasks | |
# 26-07-18 Enhanced the display of Execution Plan | |
# 11-09-18 Display SQL Advisor recommendation for the statement if it was already been vetted by SQL Advisor. | |
# 28-08-19 Added Post Tuning note for hard parsing enforcement command. | |
# 10-06-20 Adjust page formatting. | |
# 02-07-20 Added Execution Plan History. | |
# 05-10-20 Added SQL PLAN BASELINE Details. | |
# 06-10-20 Added the feature of fixing an EXECUTION PLAN by creating a new BASELINE. | |
# 06-10-20 Added the feature of fixing an EXECUTION PLAN from an EXIST BASELINE [if found]. | |
# 11-10-20 Added a hint to help the user display the complete execution plan for a plan inside the BASELINE. | |
# 13-02-21 Search the Execution Plans in AWR if the SQLID is not loaded in Cursor Cache. | |
# 15-02-21 Show Drop Baseline SQL command for the user. | |
# 19-09-21 Add the option of manually adding a plan to the SQL PLAN BASELINE using plan HASH VALUE. | |
# 19-09-21 Control the SQLID displayed statistics history in days using HIST_DAYS variable. | |
# 13-07-22 Setting SQLPLUS WRAP to ON to show the complete SQL statement. | |
# ######################################################################################################################################## | |
# ########### | |
# Description: | |
# ########### | |
echo | |
echo "=====================================================================================================" | |
echo "This script display SQLTEXT, BIND VARIABLES, EXEC PLAN, BASELINE, FIX PLAN, SQL TUNING of a SQLID ..." | |
echo "=====================================================================================================" | |
echo | |
ORACLE_OWNER_VFY="N" | |
SKIPDBS="ASM\|MGMTDB|APX" | |
HIST_DAYS=10 # Define how many DAYs back the script will dig for SQLID statistics. | |
# ####################################### | |
# Excluded INSTANCES: | |
# ####################################### | |
# Here you can mention the instances the script will IGNORE and will NOT run against: | |
# Use pipe "|" as a separator between each instance name. | |
# e.g. Excluding: -MGMTDB, ASM instances: | |
EXL_DB="\-MGMTDB|ASM|APX" #Excluded INSTANCES [Will not get reported offline]. | |
# ########################### | |
# Listing Available Databases: | |
# ########################### | |
# Count Instance Numbers: | |
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l ) | |
# Exit if No DBs are running: | |
if [ $INS_COUNT -eq 0 ] | |
then | |
echo "No Database is Running !" | |
echo | |
return | |
fi | |
# If there is ONLY one DB set it as default without prompt for selection: | |
if [ $INS_COUNT -eq 1 ] | |
then | |
export ORACLE_SID=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $NF}'|sed -e 's/ora_pmon_//g'|grep -v sed|grep -v "s///g" ) | |
# If there is more than one DB ASK the user to select: | |
elif [ $INS_COUNT -gt 1 ] | |
then | |
echo | |
echo "Select the ORACLE_SID:[Enter the number]" | |
echo "---------------------" | |
select DB_ID in $( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $NF}'|sed -e 's/ora_pmon_//g'|grep -v sed|grep -v "s///g" ) | |
do | |
integ='^[0-9]+$' | |
if ! [[ ${REPLY} =~ ${integ} ]] || [ ${REPLY} -gt ${INS_COUNT} ] || [ ${REPLY} -eq 0 ] | |
then | |
echo | |
echo "Error: Not a valid number!" | |
echo | |
echo "Enter a valid NUMBER from the displayed list !: i.e. Enter a number from [1 to ${INS_COUNT}]" | |
echo "----------------------------------------------" | |
else | |
export ORACLE_SID=$DB_ID | |
echo | |
printf "`echo "Selected Instance: ["` `echo -e "\033[33;5m${DB_ID}\033[0m"` `echo "]"`\n" | |
echo | |
break | |
fi | |
done | |
fi | |
# Exit if the user selected a Non Listed Number: | |
if [ -z "${ORACLE_SID}" ] | |
then | |
echo "You've Entered An INVALID ORACLE_SID" | |
exit | |
fi | |
# ######################### | |
# Getting ORACLE_HOME | |
# ######################### | |
ORA_USER=`ps -ef|grep ${ORACLE_SID}|grep pmon|grep -v grep|egrep -v ${EXL_DB}|grep -v "\-MGMTDB"|awk '{print $1}'|tail -1` | |
USR_ORA_HOME=`grep -i "^${ORA_USER}:" /etc/passwd| cut -f6 -d ':'|tail -1` | |
# SETTING ORATAB: | |
if [ -f /etc/oratab ] | |
then | |
ORATAB=/etc/oratab | |
export ORATAB | |
## If OS is Solaris: | |
elif [ -f /var/opt/oracle/oratab ] | |
then | |
ORATAB=/var/opt/oracle/oratab | |
export ORATAB | |
fi | |
# ATTEMPT1: Get ORACLE_HOME using pwdx command: | |
export PGREP=`which pgrep` | |
export PWDX=`which pwdx` | |
if [[ -x ${PGREP} ]] && [[ -x ${PWDX} ]] | |
then | |
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'` | |
export PMON_PID | |
ORACLE_HOME=`pwdx ${PMON_PID} 2>/dev/null|awk '{print $NF}'|sed -e 's/\/dbs//g'` | |
export ORACLE_HOME | |
fi | |
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file: | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
## If OS is Linux: | |
if [ -f /etc/oratab ] | |
then | |
ORATAB=/etc/oratab | |
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'` | |
export ORACLE_HOME | |
## If OS is Solaris: | |
elif [ -f /var/opt/oracle/oratab ] | |
then | |
ORATAB=/var/opt/oracle/oratab | |
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'` | |
export ORACLE_HOME | |
fi | |
fi | |
# ATTEMPT3: If ORACLE_HOME is in /etc/oratab, use dbhome command: | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
ORACLE_HOME=`dbhome "${ORACLE_SID}"` | |
export ORACLE_HOME | |
fi | |
# ATTEMPT4: If ORACLE_HOME is still not found, search for the environment variable: [Less accurate] | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
ORACLE_HOME=`env|grep -i ORACLE_HOME|sed -e 's/ORACLE_HOME=//g'` | |
export ORACLE_HOME | |
fi | |
# ATTEMPT5: If ORACLE_HOME is not found in the environment search user's profile: [Less accurate] | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
ORACLE_HOME=`grep -h 'ORACLE_HOME=\/' ${USR_ORA_HOME}/.bash_profile ${USR_ORA_HOME}/.*profile | perl -lpe'$_ = reverse' |cut -f1 -d'=' | perl -lpe'$_ = reverse'|tail -1` | |
export ORACLE_HOME | |
fi | |
# ATTEMPT6: If ORACLE_HOME is still not found, search for orapipe: [Least accurate] | |
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ] | |
then | |
if [ -f /usr/bin/locate ] | |
then | |
ORACLE_HOME=`locate -i orapipe|head -1|sed -e 's/\/bin\/orapipe//g'` | |
export ORACLE_HOME | |
fi | |
fi | |
export LD_LIBRARY_PATH=${ORACLE_HOME}/lib | |
# ######################################## | |
# Exit if the user is not the Oracle Owner: | |
# ######################################## | |
case ${ORACLE_OWNER_VFY} in | |
"Y") | |
CURR_USER=`whoami` | |
if [ ${ORA_USER} != ${CURR_USER} ]; then | |
echo "" | |
echo "You're Running This Sctipt with User: \"${CURR_USER}\" !!!" | |
echo "Please Run This Script With The Right OS User: \"${ORA_USER}\"" | |
echo "Script Terminated!" | |
exit | |
fi;; | |
esac | |
# ######################################## | |
# SQLPLUS: Check SQL FULLTEXT & EXEC PLAN: | |
# ######################################## | |
# Variables | |
echo | |
echo "Enter the SQL_ID:" | |
echo "================" | |
while read SQLID | |
do | |
VAL1=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set feedback off | |
SELECT COUNT(*) FROM V\$SQL WHERE SQL_ID='${SQLID}'; | |
EOF | |
) | |
VAL2=`echo ${VAL1}| awk '{print $NF}'` | |
if [ ${VAL2} -gt 0 ] | |
then | |
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set feedback off | |
set linesize 156 pages 50000 long 2000000000 | |
col SQL_FULLTEXT for a140 | |
PROMPT | |
PROMPT ************************* | |
PROMPT Statement Info: [Per Execution | in Seconds] | |
PROMPT ************************* | |
SET LONG 999999999 PAGESIZE 10000 LINESIZE 200 | |
col "ELAPSED|CPU TIME" for a16 | |
col "PLSQL|JAVA TIME" for a24 | |
col "APP|USR_IO|CLS WAIT" for a19 | |
col "BUF_GET|DISK_R|DIRECT_W" for a23 | |
col P_MEM_MB for 99999999 | |
col "ROWS" for 999999999 | |
col MODULE for a15 | |
col FIRST_LOAD_TIME for a19 | |
col LAST_LOAD_TIME for a19 | |
col sql_plan_baseline for a30 | |
col plan_hash_value for 999999999999999 | |
col signature for 99999999999999999999 | |
col SQL_PROFILE for a35 | |
VARIABLE A REFCURSOR; | |
DECLARE | |
l_cursor SYS_REFCURSOR; | |
BEGIN | |
open :A for | |
select executions EXEC,round(ELAPSED_TIME /1000000/(case when executions=0 then 1 else executions end),2) ||' | '|| round(CPU_TIME /1000000/(case when executions=0 then 1 else executions end),2) "ELAPSED|CPU TIME", | |
--round(d.ELAPSED_TIME /1000000/(case when executions=0 then 1 else executions end),2) ELAPSED_TIME, | |
round(APPLICATION_WAIT_TIME /1000000/(case when executions=0 then 1 else executions end),2) ||' | '|| round(USER_IO_WAIT_TIME /1000000/(case when executions=0 then 1 else executions end),2) ||' | '|| round(CLUSTER_WAIT_TIME /1000000/(case when executions=0 then 1 else executions end),2) "APP|USR_IO|CLS WAIT", | |
--round(PLSQL_EXEC_TIME /1000000/(case when executions=0 then 1 else executions end),2)||' | '||round(JAVA_EXEC_TIME/1000000/(case when executions=0 then 1 else executions end),2) "PLSQL|JAVA TIME", | |
round(ROWS_PROCESSED /(case when executions=0 then 1 else executions end),1)"ROWS", | |
round(BUFFER_GETS /(case when executions=0 then 1 else executions end),2) ||' | '|| round(DISK_READS /(case when executions=0 then 1 else executions end),2) ||' | '|| round(DIRECT_WRITES /(case when executions=0 then 1 else executions end),2) "BUF_GET|DISK_R|DIRECT_W", | |
--round(PERSISTENT_MEM/1024/1024,2) "P_MEM_MB", | |
substr(MODULE,1,15)"MODULE", FIRST_LOAD_TIME, LAST_LOAD_TIME | |
--,SQL_PLAN_BASELINE, SQL_PROFILE | |
from v\$sql where SQL_ID='${SQLID}'; | |
END; | |
/ | |
PRINT A; | |
/ | |
PROMPT | |
PROMPT ************************* | |
PROMPT BIND VARIABLES + SQL TEXT: | |
PROMPT ************************* | |
set heading off wrap on | |
SET LONG 999999999 PAGESIZE 10000 LINESIZE 200 | |
select 'VARIABLE '||trim (leading ':' from name)||' '||case when datatype_string= 'DATE' then 'VARCHAR2(60)' else datatype_string end||';' from v\$sql_bind_capture | |
where SQL_ID='${SQLID}' and CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql_bind_capture where SQL_ID='${SQLID}'); | |
select 'EXECUTE '||name||' := '||''''||value_string||''''||';' from v\$sql_bind_capture | |
where SQL_ID='${SQLID}' and CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql_bind_capture where SQL_ID='${SQLID}'); | |
select sql_fulltext from v\$sql where sql_id='${SQLID}' and CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql where SQL_ID='${SQLID}'); | |
set heading on | |
PROMPT | |
set heading off | |
select 'Notes: (11g Onwards)' from dual; | |
PROMPT ------- | |
select | |
decode(IS_BIND_SENSITIVE,'Y','- The Bind Variables for this statement are Being CHANGED.','N','- The Bind Variables for this statement have NEVER CHANGED.'), | |
decode(IS_BIND_AWARE,'Y','- Adaptive Cursor Sharing CHANGED the initial execution plan for that SQL_ID at least one time.','N',''), | |
' Child Number: '||CHILD_NUMBER | |
from v\$sql where sql_id='${SQLID}' and CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql where SQL_ID='${SQLID}'); | |
set heading on | |
/* | |
PROMPT | |
PROMPT | |
PROMPT ********************* | |
PROMPT BIND VARIABLE VALUES: | |
PROMPT ********************* | |
col BIND_VARIABLE for a20 | |
col VALUE for a100 | |
col DATATYPE for a20 | |
select name BIND_VARIABLE,value_string VALUE,datatype_string DATATYPE from v\$sql_bind_capture | |
where SQL_ID='${SQLID}' and CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql_bind_capture where SQL_ID='${SQLID}'); | |
PROMPT SEARCH STATSPACK TABLES: [May take very long time] | |
PROMPT *********************** | |
select SQL_TEXT from STATS\$SQLTEXT where sql_id='${SQLID}'; | |
select executions from STATS\$SQL_SUMMARY where sql_id='${SQLID}'; | |
*/ | |
PROMPT | |
PROMPT | |
PROMPT ********************* | |
PROMPT EXECUTION PLAN: | |
PROMPT ********************* | |
col PLAN_TABLE_OUTPUT for a156 | |
--SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR(('${SQLID}'))); | |
select plan_table_output from table(dbms_xplan.display_cursor('${SQLID}',null,'all')); | |
PROMPT | |
PROMPT ****************************** | |
PROMPT Execution Plan History Summary: [Change of PLAN_HASH_VALUE means a new Execution Plan] | |
PROMPT ****************************** | |
select distinct to_char(TIMESTAMP,'DD-MON-YY HH24:MI:SS') TIMESTAMP,SQL_ID,PLAN_HASH_VALUE from DBA_HIST_SQL_PLAN where sql_id='${SQLID}' group by TIMESTAMP,SQL_ID,PLAN_HASH_VALUE order by TIMESTAMP; | |
PROMPT | |
PROMPT | |
PROMPT *********************** | |
PROMPT EXECUTION PLAN History: Written By: Tim Gorman (Evergreen Database Technologies, Inc.) | |
PROMPT *********************** | |
/********************************************************************** | |
* File: sqlhistory.sql | |
* Type: SQL*Plus script | |
* Author: Tim Gorman (Evergreen Database Technologies, Inc.) | |
* Date: 29sep08 | |
* | |
* Description: | |
* SQL*Plus script to query the "history" of a specified SQL | |
* statement, using its "SQL ID" across all database instances | |
* in a database, using the AWR repository. This report is useful | |
* for obtaining an hourly perspective on SQL statements seen in | |
* more aggregated reports. | |
* | |
* Modifications: | |
* TGorman 29sep08 adapted from the earlier STATSPACK-based | |
* "sphistory.sql" script | |
*********************************************************************/ | |
set echo off | |
set feedback off timing off verify off linesize 200 pages 50000 recsep off echo off | |
set serveroutput on size 1000000 | |
col phv heading "Plan|Hash Value" | |
col snap_time format a12 truncate heading "Snapshot|Time" | |
col execs format 999,999,990 heading "Execs" | |
col lio_per_exec format 999,999,999,990.00 heading "Avg Logical IO|Per Exec" | |
col pio_per_exec format 999,999,999,990.00 heading "Avg Physical IO|Per Exec" | |
col cpu_per_exec format 999,999,999,990.00 heading "Avg|CPU (secs)|Per Exec" | |
col ela_per_exec format 999,999,999,990.00 heading "Avg|Elapsed (secs)|Per Exec" | |
col sql_text format a64 heading "Text of SQL statement" | |
clear breaks computes | |
ttitle off | |
btitle off | |
--variable v_nbr_days number | |
declare | |
cursor get_phv(in_sql_id in varchar2, in_days in integer) | |
is | |
select ss.plan_hash_value, | |
min(s.begin_interval_time) min_time, | |
max(s.begin_interval_time) max_time, | |
min(s.snap_id) min_snap, | |
max(s.snap_id) max_snap, | |
sum(ss.executions_delta) sum_execs, | |
sum(ss.disk_reads_delta) sum_disk_reads, | |
sum(ss.buffer_gets_delta) sum_buffer_gets, | |
sum(ss.cpu_time_delta)/1000000 sum_cpu_time, | |
sum(ss.elapsed_time_delta)/1000000 sum_elapsed_time | |
from dba_hist_sqlstat ss, | |
dba_hist_snapshot s | |
where ss.dbid = s.dbid | |
and ss.instance_number = s.instance_number | |
and ss.snap_id = s.snap_id | |
and ss.sql_id = in_sql_id | |
/* and ss.executions_delta > 0 */ | |
and s.begin_interval_time >= sysdate-in_days | |
group by ss.plan_hash_value | |
order by sum_elapsed_time desc; | |
-- | |
cursor get_xplan(in_sql_id in varchar2, in_phv in number) | |
is | |
select plan_table_output | |
from table(dbms_xplan.display_awr(in_sql_id, in_phv, null, 'ALL -ALIAS')); | |
-- | |
v_prev_plan_hash_value number := -1; | |
v_text_lines number := 0; | |
v_errcontext varchar2(100); | |
v_errmsg varchar2(100); | |
v_display_sql_text boolean; | |
-- | |
begin | |
/* | |
v_errcontext := 'query NBR_DAYS from DUAL'; | |
select decode('100','',10,to_number(nvl('100','10'))) | |
into :v_nbr_days | |
from dual; | |
*/ | |
v_errcontext := 'open/fetch get_phv'; | |
--for phv in get_phv('${SQLID}', :v_nbr_days) loop | |
for phv in get_phv('${SQLID}', ${HIST_DAYS}) loop | |
-- | |
if get_phv%rowcount = 1 then | |
-- | |
dbms_output.put_line('+'|| | |
rpad('-',12,'-')|| | |
rpad('-',10,'-')|| | |
rpad('-',10,'-')|| | |
rpad('-',12,'-')|| | |
rpad('-',15,'-')|| | |
rpad('-',15,'-')|| | |
rpad('-',12,'-')|| | |
rpad('-',12,'-')||'+'); | |
dbms_output.put_line('|'|| | |
rpad('Plan HV',12,' ')|| | |
rpad('Min Snap',10,' ')|| | |
rpad('Max Snap',10,' ')|| | |
rpad('Execs',12,' ')|| | |
rpad('LIO',15,' ')|| | |
rpad('PIO',15,' ')|| | |
rpad('CPU',12,' ')|| | |
rpad('Elapsed',12,' ')||'|'); | |
dbms_output.put_line('+'|| | |
rpad('-',12,'-')|| | |
rpad('-',10,'-')|| | |
rpad('-',10,'-')|| | |
rpad('-',12,'-')|| | |
rpad('-',15,'-')|| | |
rpad('-',15,'-')|| | |
rpad('-',12,'-')|| | |
rpad('-',12,'-')||'+'); | |
-- | |
end if; | |
-- | |
dbms_output.put_line('|'|| | |
rpad(trim(to_char(phv.plan_hash_value)),12,' ')|| | |
rpad(trim(to_char(phv.min_snap)),10,' ')|| | |
rpad(trim(to_char(phv.max_snap)),10,' ')|| | |
rpad(trim(to_char(phv.sum_execs,'999,999,990')),12,' ')|| | |
rpad(trim(to_char(phv.sum_buffer_gets,'999,999,999,990')),15,' ')|| | |
rpad(trim(to_char(phv.sum_disk_reads,'999,999,999,990')),15,' ')|| | |
rpad(trim(to_char(phv.sum_cpu_time,'999,990.00')),12,' ')|| | |
rpad(trim(to_char(phv.sum_elapsed_time,'999,990.00')),12,' ')||'|'); | |
-- | |
v_errcontext := 'fetch/close get_phv'; | |
-- | |
end loop; | |
dbms_output.put_line('+'|| | |
rpad('-',12,'-')|| | |
rpad('-',10,'-')|| | |
rpad('-',10,'-')|| | |
rpad('-',12,'-')|| | |
rpad('-',15,'-')|| | |
rpad('-',15,'-')|| | |
rpad('-',12,'-')|| | |
rpad('-',12,'-')||'+'); | |
-- | |
v_errcontext := 'open/fetch get_phv'; | |
--for phv in get_phv('${SQLID}', :v_nbr_days) loop | |
for phv in get_phv('${SQLID}', ${HIST_DAYS}) loop | |
-- | |
if v_prev_plan_hash_value <> phv.plan_hash_value then | |
-- | |
v_prev_plan_hash_value := phv.plan_hash_value; | |
v_display_sql_text := FALSE; | |
-- | |
v_text_lines := 0; | |
v_errcontext := 'open/fetch get_xplan'; | |
for s in get_xplan('${SQLID}', phv.plan_hash_value) loop | |
-- | |
if v_text_lines = 0 then | |
dbms_output.put_line('.'); | |
dbms_output.put_line('========== PHV = ' || | |
phv.plan_hash_value || | |
'=========='); | |
dbms_output.put_line('First seen from "'|| | |
to_char(phv.min_time,'MM/DD/YY HH24:MI:SS') || | |
'" (snap #'||phv.min_snap||')'); | |
dbms_output.put_line('Last seen from "'|| | |
to_char(phv.max_time,'MM/DD/YY HH24:MI:SS') || | |
'" (snap #'||phv.max_snap||')'); | |
dbms_output.put_line('.'); | |
dbms_output.put_line( | |
rpad('Execs',15,' ')|| | |
rpad('LIO',15,' ')|| | |
rpad('PIO',15,' ')|| | |
rpad('CPU',15,' ')|| | |
rpad('Elapsed',15,' ')); | |
dbms_output.put_line( | |
rpad('=====',15,' ')|| | |
rpad('===',15,' ')|| | |
rpad('===',15,' ')|| | |
rpad('===',15,' ')|| | |
rpad('=======',15,' ')); | |
dbms_output.put_line( | |
rpad(trim(to_char(phv.sum_execs,'999,999,999,990')),15,' ')|| | |
rpad(trim(to_char(phv.sum_buffer_gets,'999,999,999,990')),15,' ')|| | |
rpad(trim(to_char(phv.sum_disk_reads,'999,999,999,990')),15,' ')|| | |
rpad(trim(to_char(phv.sum_cpu_time,'999,999,990.00')),15,' ')|| | |
rpad(trim(to_char(phv.sum_elapsed_time,'999,999,990.00')),15,' ')); | |
dbms_output.put_line('.'); | |
end if; | |
-- | |
if v_display_sql_text = FALSE and | |
s.plan_table_output like 'Plan hash value: %' then | |
-- | |
v_display_sql_text := TRUE; | |
-- | |
end if; | |
-- | |
if v_display_sql_text = TRUE then | |
-- | |
dbms_output.put_line(s.plan_table_output); | |
-- | |
end if; | |
-- | |
v_text_lines := v_text_lines + 1; | |
-- | |
end loop; | |
-- | |
end if; | |
-- | |
v_errcontext := 'fetch/close get_phv'; | |
-- | |
end loop; | |
-- | |
exception | |
when others then | |
v_errmsg := sqlerrm; | |
raise_application_error(-20000, v_errcontext || ': ' || v_errmsg); | |
end; | |
/ | |
break on report | |
compute sum of execs on report | |
compute avg of lio_per_exec on report | |
compute avg of pio_per_exec on report | |
compute avg of cpu_per_exec on report | |
compute avg of ela_per_exec on report | |
ttitle center 'Summary Execution Statistics Over Time' | |
select to_char(s.begin_interval_time, 'DD-MON HH24:MI') snap_time, | |
ss.executions_delta execs, | |
ss.buffer_gets_delta/decode(ss.executions_delta,0,1,ss.executions_delta) lio_per_exec, | |
ss.disk_reads_delta/decode(ss.executions_delta,0,1,ss.executions_delta) pio_per_exec, | |
(ss.cpu_time_delta/1000000)/decode(ss.executions_delta,0,1,ss.executions_delta) cpu_per_exec, | |
(ss.elapsed_time_delta/1000000)/decode(ss.executions_delta,0,1,ss.executions_delta) ela_per_exec | |
from dba_hist_snapshot s, | |
dba_hist_sqlstat ss | |
where ss.dbid = s.dbid | |
and ss.instance_number = s.instance_number | |
and ss.snap_id = s.snap_id | |
and ss.sql_id = '${SQLID}' | |
/* and ss.executions_delta > 0 */ | |
--and s.begin_interval_time >= sysdate - :v_nbr_days | |
and s.begin_interval_time >= sysdate - ${HIST_DAYS} | |
order by s.snap_id; | |
clear breaks computes | |
set verify on echo on feedback on | |
ttitle off | |
PROMPT | |
PROMPT ****************************** | |
PROMPT Execution Plan History Summary: [Change of PLAN_HASH_VALUE means a new Execution Plan] | |
PROMPT ****************************** | |
select distinct to_char(TIMESTAMP,'DD-MON-YY HH24:MI:SS') TIMESTAMP,SQL_ID,PLAN_HASH_VALUE from DBA_HIST_SQL_PLAN where sql_id='${SQLID}' group by TIMESTAMP,SQL_ID,PLAN_HASH_VALUE order by TIMESTAMP; | |
/* | |
PROMPT | |
PROMPT *********************** | |
PROMPT SQL PLAN BASELINE: [For ${SQLID}] | |
PROMPT *********************** | |
col signature format 99999999999999999999 | |
col sql_handle format a25 | |
col plan_name format a30 | |
col ELAPSED_TIME for 9999999.99 | |
col CPU_TIME for 9999999.99 | |
col BUFFER_GETS for 9999999.99 | |
col enabled format a5 | |
col accepted format a5 | |
col fixed format a5 | |
select distinct d.plan_name, d.sql_handle, d.signature, d.OPTIMIZER_COST COST, d.executions, | |
round(d.ELAPSED_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) ELAPS_TIME, | |
round(d.CPU_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) CPU_TIME, | |
round(d.BUFFER_GETS /1000000/(case when d.executions=0 then 1 else d.executions end),2) BUFFER_GETS, | |
d.enabled, d.accepted, d.fixed, | |
to_char(d.LAST_EXECUTED,'DDMONYY HH24:MI:SS') LAST_EXECUTED | |
from dba_sql_plan_baselines d, v\$sql s | |
where s.sql_id='${SQLID}' | |
and d.signature = s.exact_matching_signature | |
--and s.CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql_bind_capture where SQL_ID='${SQLID}') | |
; | |
*/ | |
EOF | |
# ###################################### | |
# Checking the Existance of SPM Feature: | |
# ###################################### | |
CHK_SPM_OPTION_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF | |
set pages 0 feedback off echo off; | |
SELECT count(*) from v\$option where parameter='SQL Plan Management' and value='TRUE'; | |
exit; | |
EOF | |
) | |
CHK_SPM_OPTION=`echo ${CHK_SPM_OPTION_RAW} | awk '{print $NF}'` | |
# IF SPM feature is available offer the option of fixing the SQL Plan through creating a BASELINE: | |
if [ ${CHK_SPM_OPTION} -eq 1 ] | |
then | |
BASELINE_PLAN_COUNT_RAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set pages 0 feedback off; | |
SELECT COUNT(*) | |
from dba_sql_plan_baselines d, v\$sql s | |
where s.sql_id='${SQLID}' | |
and d.signature = s.exact_matching_signature | |
--and s.CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql_bind_capture where SQL_ID='${SQLID}') | |
; | |
exit; | |
EOF | |
) | |
BASELINE_PLAN_COUNT=`echo ${BASELINE_PLAN_COUNT_RAW}| awk '{print $NF}'` | |
# IF no Baseline found, offer to create a new baseline from current available plans from CURSOR CACHE and fix the plan: | |
if [ ${BASELINE_PLAN_COUNT} -le 0 ] | |
then | |
echo "" | |
echo "Do you want to FIX a plan for [${SQLID}] by creating a NEW BASELINE: [Y|N]" | |
echo "=========================================================================" | |
while read INPUT | |
do | |
case ${INPUT} in | |
y|Y|yes|YES|Yes) | |
echo "" | |
echo "Creating a BASELINE for [${SQLID}] containing the current loaded plans from cursor cache" | |
PLANS_COUNT_RAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set pages 0 feedback off; | |
set serveroutput on | |
declare | |
plans_loaded pls_integer ; | |
begin | |
plans_loaded := dbms_spm.load_plans_from_cursor_cache( sql_id => '${SQLID}' ) ; | |
dbms_output.put_line( 'plans loaded: '||plans_loaded ) ; | |
end ; | |
/ | |
exit; | |
EOF | |
) | |
PLANS_COUNT=`echo ${PLANS_COUNT_RAW}| awk '{print $NF}'` | |
if [ ${PLANS_COUNT} -gt 0 ] | |
then | |
echo "" | |
echo "Loaded Plans: ${PLANS_COUNT}" | |
echo "" | |
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set pages 1000 lines 169 pages 50000 long 2000000000 | |
col signature format 99999999999999999999 | |
col sql_handle format a25 | |
col plan_name format a30 | |
col ELAPSED_TIME for 9999999.99 | |
col CPU_TIME for 9999999.99 | |
col BUFFER_GETS for 9999999.99 | |
col enabled format a5 | |
col accepted format a5 | |
col fixed format a5 | |
PROMPT | |
PROMPT CURRENT PLANS INSIDE THE NEW BASELINE for [${SQLID}]: | |
PROMPT | |
select distinct d.plan_name, d.sql_handle, d.signature, d.OPTIMIZER_COST COST, d.executions, | |
round(d.ELAPSED_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) ELAPSED_TIME, | |
round(d.CPU_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) CPU_TIME, | |
round(d.BUFFER_GETS /1000000/(case when d.executions=0 then 1 else d.executions end),2) BUFFER_GETS, | |
d.enabled, d.accepted, d.fixed | |
from dba_sql_plan_baselines d, v\$sql s | |
where sql_id='${SQLID}' | |
and d.signature = s.exact_matching_signature | |
--and s.CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql_bind_capture where SQL_ID='${SQLID}') | |
; | |
EOF | |
read -p "Enter the PLAN_NAME for the plan you want to fix [From the above output]: " PLAN_NAME | |
read -p "Enter the SQL_HANDLE for the plan you want to fix [From the above output]: " SQL_HANDLE | |
echo "" | |
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set pages 1000 feedback off lines 169 long 2000000000 | |
col signature format 99999999999999999999 | |
col sql_handle format a25 | |
col plan_name format a30 | |
col ELAPSED_TIME for 9999999.99 | |
col CPU_TIME for 9999999.99 | |
col BUFFER_GETS for 9999999.99 | |
col enabled format a5 | |
col accepted format a5 | |
col fixed format a5 | |
set serveroutput on | |
declare | |
plans_loaded pls_integer ; | |
begin | |
plans_loaded := dbms_spm.alter_sql_plan_baseline( | |
sql_handle => '${SQL_HANDLE}', | |
plan_name => '${PLAN_NAME}', | |
attribute_name => 'fixed', | |
attribute_value =>'YES' | |
) ; | |
dbms_output.put_line( 'plans modified: '||plans_loaded ) ; | |
end ; | |
/ | |
PROMPT | |
select distinct d.plan_name, d.sql_handle, d.signature, d.OPTIMIZER_COST COST, d.executions, | |
round(d.ELAPSED_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) ELAPSED_TIME, | |
round(d.CPU_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) CPU_TIME, | |
round(d.BUFFER_GETS /1000000/(case when d.executions=0 then 1 else d.executions end),2) BUFFER_GETS, | |
d.enabled, d.accepted, d.fixed | |
from dba_sql_plan_baselines d, v\$sql s | |
where sql_id='${SQLID}' | |
and d.signature = s.exact_matching_signature | |
--and s.CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql_bind_capture where SQL_ID='${SQLID}') | |
; | |
set escape on feedback off echo off pages 0 | |
-- Set SQL_HANDLE: | |
column SQL_HANDLE NEW_VALUE SQL_HANDLE; | |
select distinct d.sql_handle SQL_HANDLE from dba_sql_plan_baselines d, v\$sql s where sql_id='${SQLID}' and d.signature = s.exact_matching_signature; | |
PROMPT | |
PROMPT -- TO ADD a PLAN to the BASELINE: [From SQLPlus] [Provide the PLAN HASH VALUE] | |
PROMPT var pls number | |
PROMPT exec :pls := dbms_spm.load_plans_from_cursor_cache(sql_id => '${SQLID}', plan_hash_value => '\&PLAN_HASH_VALUE', sql_handle => '&SQL_HANDLE');; | |
PROMPT | |
PROMPT -- TO DROP a PLAN: [From SQLPlus] [Provide the PLAN NAME] | |
PROMPT var pls number | |
PROMPT exec :pls := dbms_spm.drop_sql_plan_baseline(plan_name => '\&PLAN_NAME');; | |
PROMPT | |
PROMPT -- TO DROP the BASELINE: [From SQLPlus] [FOR ROLLBACK PURPOSE] | |
PROMPT var pls number | |
PROMPT exec :pls := dbms_spm.drop_sql_plan_baseline(sql_handle => '&SQL_HANDLE');; | |
PROMPT | |
EOF | |
fi | |
break;; | |
*) break;; | |
esac | |
done | |
fi | |
# IF SQL BASELINE is already exist, but having more than one plan, offer the option to change/fix the plan from the list of baseline plans: | |
#if [ ${BASELINE_PLAN_COUNT} -gt 1 ] | |
if [ ${BASELINE_PLAN_COUNT} -ge 1 ] | |
then | |
#echo "" | |
#echo -e "\033[33;5mMultiple Plans Detected for this SQLID ...\033[0m" | |
echo "" | |
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
PROMPT | |
PROMPT *********************** | |
PROMPT SQL PLAN BASELINE: [For ${SQLID}] | |
PROMPT *********************** | |
set pages 1000 lines 169 pages 50000 long 2000000000 | |
col signature format 99999999999999999999 | |
col sql_handle format a25 | |
col plan_name format a30 | |
col ELAPSED_TIME for 9999999.99 | |
col CPU_TIME for 9999999.99 | |
col BUFFER_GETS for 9999999.99 | |
col enabled format a5 | |
col accepted format a5 | |
col fixed format a5 | |
col LAST_EXECUTED format a13 | |
select distinct d.plan_name, d.sql_handle, d.signature, d.OPTIMIZER_COST COST, d.executions, | |
round(d.ELAPSED_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) ELAPS_TIME, | |
round(d.CPU_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) CPU_TIME, | |
round(d.BUFFER_GETS /1000000/(case when d.executions=0 then 1 else d.executions end),2) BUFFER_GETS, | |
d.enabled, d.accepted, d.fixed, | |
to_char(d.LAST_EXECUTED,'DDMONYY HH24:MI') LAST_EXECUTED | |
from dba_sql_plan_baselines d, v\$sql s | |
where s.sql_id='${SQLID}' | |
and d.signature = s.exact_matching_signature | |
--and s.CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql_bind_capture where SQL_ID='${SQLID}') | |
; | |
set escape on feedback off echo off pages 0 | |
-- Set SQL_HANDLE: | |
column SQL_HANDLE NEW_VALUE SQL_HANDLE | |
select distinct d.sql_handle SQL_HANDLE from dba_sql_plan_baselines d, v\$sql s where sql_id='${SQLID}' and d.signature = s.exact_matching_signature; | |
PROMPT | |
PROMPT -- TO ADD a PLAN to the BASELINE: [From SQLPlus] [Provide the PLAN HASH VALUE] | |
PROMPT var pls number | |
PROMPT exec :pls := dbms_spm.load_plans_from_cursor_cache(sql_id => '${SQLID}', plan_hash_value => '\&PLAN_HASH_VALUE', sql_handle => '&SQL_HANDLE');; | |
PROMPT | |
PROMPT -- TO DROP a PLAN: [From SQLPlus] [Provide the PLAN NAME] | |
PROMPT var pls number | |
PROMPT exec :pls := dbms_spm.drop_sql_plan_baseline(plan_name => '\&PLAN_NAME');; | |
PROMPT | |
PROMPT -- TO DROP the BASELINE: [From SQLPlus] [FOR ROLLBACK PURPOSE] | |
PROMPT var pls number | |
PROMPT exec :pls := dbms_spm.drop_sql_plan_baseline(sql_handle => '&SQL_HANDLE');; | |
EOF | |
echo "" | |
echo "Do you want to FIX a plan for [${SQLID}] in the CURRENT exist BASELINE: [Y|N]" | |
echo "============================================================================" | |
while read ANS | |
do | |
case ${ANS} in | |
y|Y|yes|YES|Yes) | |
echo "" | |
read -p "Enter the PLAN_NAME for the plan you want to fix [From the above query output]: " PLAN_NAME | |
read -p "Enter the SQL_HANDLE for the plan you want to fix [From the above query output]: " SQL_HANDLE | |
echo "" | |
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set pages 1000 feedback off lines 169 pages 50000 long 2000000000 | |
col signature format 99999999999999999999 | |
col sql_handle format a25 | |
col plan_name format a30 | |
col ELAPSED_TIME for 9999999.99 | |
col CPU_TIME for 9999999.99 | |
col BUFFER_GETS for 9999999.99 | |
col enabled format a5 | |
col accepted format a5 | |
col fixed format a5 | |
set serveroutput on | |
declare | |
plans_loaded pls_integer ; | |
begin | |
plans_loaded := dbms_spm.alter_sql_plan_baseline( | |
sql_handle => '${SQL_HANDLE}', | |
plan_name => '${PLAN_NAME}', | |
attribute_name => 'fixed', | |
attribute_value =>'YES' | |
) ; | |
dbms_output.put_line( 'plans modified: '||plans_loaded ) ; | |
end ; | |
/ | |
PROMPT | |
select distinct d.plan_name, d.sql_handle, d.signature, d.OPTIMIZER_COST COST, d.executions, | |
round(d.ELAPSED_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) ELAPSED_TIME, | |
round(d.CPU_TIME /1000000/(case when d.executions=0 then 1 else d.executions end),2) CPU_TIME, | |
round(d.BUFFER_GETS /1000000/(case when d.executions=0 then 1 else d.executions end),2) BUFFER_GETS, | |
d.enabled, d.accepted, d.fixed | |
from dba_sql_plan_baselines d, v\$sql s | |
where sql_id='${SQLID}' | |
and d.signature = s.exact_matching_signature | |
--and s.CHILD_NUMBER = (select max(CHILD_NUMBER) from v\$sql_bind_capture where SQL_ID='${SQLID}') | |
; | |
set escape on feedback off echo off pages 0 | |
-- Set SQL_HANDLE: | |
column SQL_HANDLE NEW_VALUE SQL_HANDLE | |
select distinct d.sql_handle SQL_HANDLE from dba_sql_plan_baselines d, v\$sql s where sql_id='${SQLID}' and d.signature = s.exact_matching_signature; | |
PROMPT | |
PROMPT -- TO ADD a PLAN to the BASELINE: [From SQLPlus] [Provide the PLAN HASH VALUE] | |
PROMPT var pls number | |
PROMPT exec :pls := dbms_spm.load_plans_from_cursor_cache(sql_id => '${SQLID}', plan_hash_value => '\&PLAN_HASH_VALUE', sql_handle => '&SQL_HANDLE');; | |
PROMPT | |
PROMPT -- TO DROP a PLAN: [From SQLPlus] [Provide the PLAN NAME] | |
PROMPT var pls number | |
PROMPT exec :pls := dbms_spm.drop_sql_plan_baseline(plan_name => '\&PLAN_NAME');; | |
PROMPT | |
PROMPT -- TO DROP the BASELINE: [From SQLPlus] [FOR ROLLBACK PURPOSE] | |
PROMPT var pls number | |
PROMPT exec :pls := dbms_spm.drop_sql_plan_baseline(sql_handle => '&SQL_HANDLE');; | |
PROMPT | |
EOF | |
break;; | |
*) break;; | |
esac | |
done | |
fi | |
fi | |
VAL_TUN_TASK_RAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set pages 0 feedback off; | |
SELECT COUNT(*) FROM DBA_ADVISOR_TASKS where TASK_NAME='${SQLID}_Tuning_Task'; | |
EOF | |
) | |
VAL_TUN_TASK=`echo ${VAL_TUN_TASK_RAW}| awk '{print $NF}'` | |
case ${VAL_TUN_TASK} in | |
1) echo | |
echo "-----------------------------------------------------------------------------------------------" | |
# echo -e "\033[33;5mA Tuning Task already been found for SQLID [${SQLID}] You can view this task result using:\033[0m" | |
echo -e "\033[33;5mA Tuning Task already been found for SQLID [${SQLID}]\033[0m" | |
echo "Displaying the Recommendations:" | |
echo "-----------------------------------------------------------------------------------------------" | |
# echo "SET LONG 2000000000 pages 10000 lines 200" | |
# echo "SELECT DBMS_SQLTUNE.report_tuning_task('${SQLID}_Tuning_Task') AS recommendations FROM dual;";; | |
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
SET LONG 999999999 PAGESIZE 10000 LINESIZE 167 | |
SELECT DBMS_SQLTUNE.report_tuning_task('${SQLID}_Tuning_Task') AS recommendations FROM dual; | |
EOF | |
;; | |
esac | |
echo "" | |
printf "`echo "Do you want to Tune SQLID [${SQLID}] Using SQL Tuning Advisor? (NO/YES) Default is [NO] |"` `echo -e "\033[33;5m[Licensed Feature]\033[0m"` \n" | |
echo "===================================================================" | |
echo "Note: Please make sure that Diagnostic & Tuning License is already acquired before using this feature." | |
while read ANS1 | |
do | |
case ${ANS1} in | |
""|n|N|no|NO|No) break ;; | |
""|y|Y|yes|YES|Yes) | |
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
--PROMPT | |
--PROMPT SQL Statement Full Text: | |
--PROMPT ----------------------- | |
--SET LONG 2000000000 PAGESIZE 10000 LINESIZE 200 | |
--col SQL_FULLTEXT for a200 | |
--select SQL_FULLTEXT from V\$SQL where SQL_ID='${SQLID}'; | |
PROMPT | |
PROMPT Creating SQL Tuning Task: "${SQLID}_Tuning_Task" ... | |
DECLARE | |
l_sql_tune_task_id VARCHAR2(100); | |
BEGIN | |
l_sql_tune_task_id := DBMS_SQLTUNE.create_tuning_task ( | |
sql_id => '${SQLID}', | |
scope => DBMS_SQLTUNE.scope_comprehensive, | |
time_limit => 3600, | |
task_name => '${SQLID}_Tuning_Task', | |
description => 'Tuning task for statement ${SQLID}'); | |
DBMS_OUTPUT.put_line('l_sql_tune_task_id: ' || l_sql_tune_task_id); | |
END; | |
/ | |
PROMPT Executing TUNING Task: "${SQLID}_Tuning_Task" ... | |
PROMPT | |
PROMPT Please Wait! This May Take Several Minutes ... | |
EXEC DBMS_SQLTUNE.execute_tuning_task(task_name => '${SQLID}_Tuning_Task'); | |
PROMPT | |
PROMPT SQL Tuning Recommendations: | |
PROMPT -------------------------- | |
spool ${SQLID}_Tuning_Task_details.log | |
SET LONG 999999999 PAGESIZE 10000 LINESIZE 200 | |
SELECT DBMS_SQLTUNE.report_tuning_task('${SQLID}_Tuning_Task') AS recommendations FROM dual; | |
PROMPT | |
PROMPT Post Tuning: You may need to enforce HARD PARSING this statement to enforce using the new execution plan: | |
PROMPT ----------- | |
PROMPT SELECT CHILD_NUMBER,ADDRESS,HASH_VALUE,LAST_LOAD_TIME FROM V\$SQL WHERE SQL_ID='${SQLID}';; | |
PROMPT EXEC FOR I IN (SELECT ADDRESS,HASH_VALUE,USERS_EXECUTING,SQL_TEXT FROM V\$SQLAREA WHERE SQL_ID='${SQLID}') LOOP SYS.DBMS_SHARED_POOL.PURGE(I.ADDRESS||','||I.HASH_VALUE,'C'); END LOOP;; | |
PROMPT SELECT CHILD_NUMBER,ADDRESS,HASH_VALUE,LAST_LOAD_TIME FROM V\$SQL WHERE SQL_ID='${SQLID}';; | |
PROMPT | |
PROMPT For Dropping Tuning Task "${SQLID}_Tuning_Task" Use this SQL command: | |
PROMPT ------------------------ | |
PROMPT EXEC dbms_sqltune.drop_tuning_task(task_name => '${SQLID}_Tuning_Task');; | |
PROMPT | |
spool off | |
EOF | |
break ;; | |
*) echo "Please enter a VALID answer [N|Y]" ;; | |
esac | |
done | |
break | |
else | |
echo | |
echo "SQLID [${SQLID}] is not found in the SHARED POOL!" | |
echo | |
echo "Searching the AWR ..." | |
echo | |
AWR_COUNT_RAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set feedback off | |
select count(*) from table(dbms_xplan.display_awr('${SQLID}')); | |
EOF | |
) | |
AWR_COUNT=`echo ${AWR_COUNT_RAW}| awk '{print $NF}'` | |
if [ ${AWR_COUNT} -gt 0 ] | |
then | |
echo "SQLID found in AWR." | |
echo | |
echo "Displaying the Execution Plans History ..." | |
echo | |
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF | |
set feedback off | |
set linesize 159 pages 50000 long 2000000000 | |
col PLAN_TABLE_OUTPUT for a156 | |
select * from table(dbms_xplan.display_awr('${SQLID}')); | |
EOF | |
else | |
echo "The given SQLID is NOT found neither in the Shared Pool nor in AWR!" | |
echo "" | |
fi | |
break | |
fi | |
done | |
# ############# | |
# END OF SCRIPT | |
# ############# | |
# REPORT BUGS to: <[email protected]>. | |
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS". | |
# DOWNLOAD THE LATEST VERSION OF DATABASE ADMINISTRATION BUNDLE FROM: http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment