Sie sind auf Seite 1von 6

Automatically running sql_advisor tasks from ADDM reports Oracl...

1 de 6

https://jhdba.wordpress.com/2009/11/12/automatically-running-sql_ad...

Oracle DBA A lifelong learning experience

Automatically running sql_advisor tasks from ADDM reports


Posted by John Hallas on November 12, 2009
STOP PRESS 17 Nov 2009 updated with latest code which works against both 10g and 11g databases
I am a aching scripts which I wrote a while ago to automatically pick any sql_ids reported in the latest ADDM and then run sql_advisor to report on
any tuning advice. I am not suggesting that the information they provide is not available from EM or indeed every task reported needs resolving but it
can be a good heads-up on a system you dont know very well.
These are enabled every hour (can be less depending upon your snapshot interval) and they create a daily le which can be easily reviewed.
I nd the real benet is not on production databases but on dev and test databases that are being used for development prior to production
implementation. This is for two reasons, rstly I hope that the team has a good handle on what is happening in production and are aware of issues and
secondly we are most likely to be able to add most value and benet in development environments before the code is made live.
A couple of issue es. The output from the ADDM report is dierent between 10g and 11g so I have amended the awk le to cater for both versions. I
have been having an ongoing problem with tghe sql_advisor tuning task timing out on some systems and consequently leaving the task created for the
next run. I have therefore amended the loop to drop the task at several points which looks untidy in the output le bit does seem to resolve the problem.
I hoped to a ach a zip le containing 4 scripts but cannot see how to do it without a plug-in which is a problem on my works PC. so in the meantime I
have pasted the code of each of 4 les.
tuning_recommendations.ksh which is the controlling script

29/08/2015 12:26

Automatically running sql_advisor tasks from ADDM reports Oracl...

2 de 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

https://jhdba.wordpress.com/2009/11/12/automatically-running-sql_ad...

#! /bin/ksh
# loop though the file produced from get_addm_report.sql and put the gathered sql-ids into a flat file
# awk the file to get just the SQL_ID
# for each sql_id create a task, execute that task, run the report and then delete the task
#
# The delete tuning task job is run an additional twice because if the tuning task times out then it does not clean up prope
# Better to see a few failures in this job that not run the sql_tuning_advisor at all.
#if [ -d /home/oracle/logs ]
then
rm /home/oracle/logs/tmp*.log
else
mkdir /home/oracle/logs
exit
fi
if [ $# -ne 1 ]
then
echo "No ORACLE SID - exiting"
exit
fi
# execute ORACLE's .profile
#
#. ~/.profile
unset ORAENV_ASK
#
# set up environment variables.
#
ORACLE_SID=$1
. /usr/local/bin/oraenv ${ORACLE_SID}
export ORACLE_HOME=`cat /etc/oratab | grep $ORACLE_SID | awk -F: '{print $2 }`
export PATH=$ORACLE_HOME/bin:$PATH
export ORAENV_ASK=NO
today=`date +%d-%b-%Y`; export today
LOGDIR=$HOME/logs
LOGFILE=$LOGDIR/get_addm_${today}.log
REPORTFILE=$LOGDIR/sql_advisor_report_${ORACLE_SID}_${today}.log
#
#
sqlplus -s /nolog <<SQLEND
connect / as sysdba
spool $LOGDIR/tmp_${ORACLE_SID}_1.log
@/shared/oracle/performance/get_addm_report.sql
spool off
exit
SQLEND
<p>&nbsp;</p>

cat $LOGDIR/tmp_${ORACLE_SID}_1.log|awk -f /shared/oracle/performance/tuning_recommendations.awk |awk '!a[$0]++' > $LOGDIR/t


cat $LOGDIR/tmp_${ORACLE_SID}_2.log | awk '$0!~/^$/ {print $0}' > $LOGDIR/tmp_${ORACLE_SID}_3.log
for PLAN in `cat $LOGDIR/tmp_${ORACLE_SID}_3.log`
do
sqlplus -s /nolog <<SQLEND >> $REPORTFILE
connect / as sysdba
begin
DBMS_SQLTUNE.drop_tuning_task('test_task1');
end;
/
SELECT status FROM USER_ADVISOR_TASKS WHERE task_name = 'test_task1';
@/shared/oracle/performance/sql_advisor.sql $PLAN
exit
SQLEND
done
# tidy up the report file
# tidy up reports > 14 days old
find $LOGDIR -name "sql_advisor_repor*.log" -mtime +14 -print -exec rm -f {} \;

get_addm_report.sql which gets each task from the last snapshot from dba_advisor_tasks
1
2
3
4
5
6
7
8
9
10
11
12

set long 10000000


set pagesize 50000
column get_clob format a80
select dbms_advisor.get_task_report (task_name) as ADDM_report
from dba_advisor_tasks
where task_id = (
select max(t. task_id)
from dba_advisor_tasks t, dba_advisor_log l
where t.task_id = l.task_id
and t.advisor_name = 'ADDM'
and l.status = 'COMPLETED');

tuning_recommendations.awk is a short awk script used to process the output from get_addm_report.sql

29/08/2015 12:26

Automatically running sql_advisor tasks from ADDM reports Oracl...

3 de 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

https://jhdba.wordpress.com/2009/11/12/automatically-running-sql_ad...

BEGIN{
#start at the first line
#OUTFILE="$HOME/logs/outfile.log"
}
{
{
if (($1=="RATIONALE:") && ($2=="SQL")) #10G ADDM format
{
F1=$6
}
if (($1=="Run") && ($2=="SQL") && ($3=="Tuning") && ($4=="Advisor") && ($7=="SQL") && ($10=="SQL_ID")) #11G
{
F1=$11
}
}
VAR1=substr(F1,2,13)
print VAR1
}
END{
}

sql_advisor.sql runs the sql_advisor package against each task found.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

DECLARE
my_task_name
my_sqltext
my_sqlid

VARCHAR2 (30);
CLOB;
varchar2(30);

BEGIN
my_sqlid := '&1';
my_task_name := dbms_sqltune.create_tuning_task (sql_id=> my_sqlid,
scope
=> 'COMPREHENSIVE',
time_limit
=> 300,
task_name
=> 'test_task1',
description
=> 'test_task1'
);
END;
/
BEGIN
dbms_sqltune.execute_tuning_task (task_name => 'test_task1');
END;
/
SELECT status FROM USER_ADVISOR_TASKS WHERE task_name = 'test_task1';
SET LONG 10000
SET LONGCHUNKSIZE 10000
SET LINESIZE 100
set pages 60
SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( 'test_task1')
FROM DUAL;
begin
DBMS_SQLTUNE.drop_tuning_task('test_task1');
end;
/

We have a read only NFS mounted disk available on all database servers and the les are placed in there and initiated by a cron entry for each SID on an
hourly basis
40 * * * * /shared/oracle/performance/tuning_recommendations.ksh SID >/dev/null 2>&1
Output is created in a folder $HOME/logs and 14 days worth of reports are kept.
A sample output report (only one task shown but certainly on this Peoplesoft database it would show many tasks)

29/08/2015 12:26

Automatically running sql_advisor tasks from ADDM reports Oracl...

4 de 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

https://jhdba.wordpress.com/2009/11/12/automatically-running-sql_ad...

DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_TASK1')
---------------------------------------------------------------------------------------------------GENERAL INFORMATION SECTION
------------------------------------------------------------------------------Tuning Task Name
: test_task1
Tuning Task Owner
: SYS
Scope
: COMPREHENSIVE
Time Limit(seconds)
: 60
Completion Status
: COMPLETED
Started at
: 11/12/2009 07:43:33
Completed at
: 11/12/2009 07:44:16
Number of Statistic Findings
: 1
Number of Index Findings
: 1
------------------------------------------------------------------------------Schema Name: SYSADM
SQL ID
: cy3fmjha2sjnr
SQL Text
: SELECT M.EMPLID, M.EMPL_RCD, M.SCH_PRIM_ALT_IND,
TO_CHAR(M.DUR,'YYYY-MM-DD'), M.SEQ_NO, M.CHNG_PRIMARY,
M.SCHEDULE_GRP, M.SETID, M.WRKDAY_ID, M.SHIFT_ID, M.SCHED_HRS,
M.SCH_CONFIG1, M.SCH_CONFIG2, M.SCH_CONFIG3, M.SCH_CONFIG4,
TO_CHAR(M.START_DTTM,'YYYY-MM-DD-HH24.MI.SS.&amp;quot;000000&amp;quot;'),
TO_CHAR(M.END_DTTM,'YYYY-MM-DD-HH24.MI.SS.&amp;quot;000000&amp;quot;'),
M.SCHED_SOURCE, M.OFFDAY_IND, A.TIMEZONE, A.SCH_CATEGORY From
PS_SCH_MNG_SCH_TBL M, PS_SCH_ADHOC_DTL A Where M.EMPLID = :1 and
M.EMPL_RCD = :2 and M.SCH_PRIM_ALT_IND = :3 and M.DUR between
TO_DATE(:4,'YYYY-MM-DD') and TO_DATE(:5,'YYYY-MM-DD') and
A.EMPLID = M.EMPLID and A.EMPL_RCD = M.EMPL_RCD and
A.SCH_PRIM_ALT_IND = M.SCH_PRIM_ALT_IND and A.DUR = M.DUR and
A.SEQ_NO = M.SEQ_NO and A.SEQNUM = 1 Order By M.DUR Asc,
M.SCHED_SOURCE Desc, M.SEQ_NO Desc
------------------------------------------------------------------------------FINDINGS SECTION (2 findings)
------------------------------------------------------------------------------1- Statistics Finding
--------------------Optimizer statistics for index &amp;quot;SYSADM&amp;quot;.&amp;quot;PS_SCH_MNG_SCH_TBL&amp;quot; are stale.
Recommendation
-------------- Consider collecting optimizer statistics for this index.
execute dbms_stats.gather_index_stats(ownname =&amp;gt; 'SYSADM', indname =&amp;gt;
'PS_SCH_MNG_SCH_TBL', estimate_percent =&amp;gt;
DBMS_STATS.AUTO_SAMPLE_SIZE);
Rationale
--------The optimizer requires up-to-date statistics for the index in order to
select a good execution plan.
2- Index Finding (see explain plans section below)
-------------------------------------------------The execution plan of this statement can be improved by creating one or more
indices.
Recommendation (estimated benefit: 94.67%)
------------------------------------------

DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_TASK1')
---------------------------------------------------------------------------------------------------- Consider running the Access Advisor to improve the physical schema design
or creating the recommended index.
create index SYSADM.IDX$$_21C0F0001 on
SYSADM.PS_SCH_ADHOC_DTL(&amp;quot;EMPLID&amp;quot;,&amp;quot;SEQNUM&amp;quot;,&amp;quot;EMPL_RCD&amp;quot;,&amp;quot;SC
R&amp;quot;);
- Consider running the Access Advisor to improve the physical schema design
or creating the recommended index.
create index SYSADM.IDX$$_21C0F0002 on
SYSADM.PS_SCH_MNG_SCH_TBL(&amp;quot;EMPLID&amp;quot;,&amp;quot;DUR&amp;quot;);
Rationale
--------Creating the recommended indices significantly improves the execution plan
of this statement. However, it might be preferable to run &amp;quot;Access Advisor&amp;quot;
using a representative SQL workload as opposed to a single statement. This
will allow to get comprehensive index recommendations which takes into
account index maintenance overhead and additional space consumption.
------------------------------------------------------------------------------EXPLAIN PLANS SECTION
------------------------------------------------------------------------------1- Original
----------Plan hash value: 2070933151
----------------------------------------------------------------------------------------------------

29/08/2015 12:26

Automatically running sql_advisor tasks from ADDM reports Oracl...

5 de 6

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

https://jhdba.wordpress.com/2009/11/12/automatically-running-sql_ad...

-----------------------| Id | Operation
| Name
| Rows | Bytes | Cost (%CPU)| Ti
me
| Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
1 |
103 |
387
(1)| 00
:00:01 |
|
|
|* 1 | FILTER
|
|
|
|
|
|
|
|
|
2 |
SORT ORDER BY
|
|
1 |
103 |
387
(1)| 00
:00:01 |
|
|
|
3 |
NESTED LOOPS
|
|
1 |
103 |
386
(1)| 00
:00:01 |
|
|
|
4 |
PARTITION RANGE ITERATOR
|
|
10 |
350 |
371
(1)| 00
:00:01 |
KEY |
KEY |
|
5 |
TABLE ACCESS BY LOCAL INDEX ROWID| PS_SCH_ADHOC_DTL
|
10 |
350 |
371
(1)| 00
:00:01 |
KEY |
KEY |
|* 6 |
INDEX RANGE SCAN
| PS_SCH_ADHOC_DTL
|
10 |
|
369
(1)| 00
:00:01 |
KEY |
KEY |
|
7 |
PARTITION RANGE ITERATOR
|
|
1 |
68 |
2
(0)| 00
:00:01 |
KEY |
KEY |
|
8 |
TABLE ACCESS BY LOCAL INDEX ROWID| PS_SCH_MNG_SCH_TBL |
1 |
68 |
2
(0)| 00
:00:01 |
KEY |
KEY |
|* 9 |
INDEX UNIQUE SCAN
| PS_SCH_MNG_SCH_TBL |
1 |
|
1
(0)| 00
:00:01 |
KEY |
KEY |
--------------------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_TASK1')
------------------------------------------------------------------------------------------------------------------------------------------------------

1 - filter(TO_DATE(:4,'YYYY-MM-DD')&amp;lt;=TO_DATE(:5,'YYYY-MM-DD'))
6 - access(&amp;quot;A&amp;quot;.&amp;quot;EMPLID&amp;quot;=:1 AND &amp;quot;A&amp;quot;.&amp;quot;EMPL_RCD&amp;quot;=TO
&amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;&amp;gt;=TO_DATE(:4,'YYYY-MM-DD') AND &amp;quot;A&amp;quot;.&amp
-MM-DD'))
filter(&amp;quot;A&amp;quot;.&amp;quot;SEQNUM&amp;quot;=1)
9 - access(&amp;quot;M&amp;quot;.&amp;quot;EMPLID&amp;quot;=:1 AND &amp;quot;M&amp;quot;.&amp;quot;EMPL_RCD&amp;quot;=TO
&amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot; AND &amp;quot;A&a
filter(&amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot;&amp;gt;=TO_DATE(:4,'YYYY-MM-DD') AND &amp;quot;M&amp;quot;.&amp
2- Using New Indices
-------------------Plan hash value: 1209469329
--------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost (%CPU)| Ti
me
| Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
1 |
103 |
21 (10)| 00
:00:01 |
|
|
|* 1 | FILTER
|
|
|
|
|
|
|
|
|
2 |
SORT ORDER BY
|
|
1 |
103 |
21 (10)| 00
:00:01 |
|
|
|* 3 |
HASH JOIN
|
|
1 |
103 |
20
(5)| 00
:00:01 |
|
|
|
4 |
TABLE ACCESS BY GLOBAL INDEX ROWID| PS_SCH_ADHOC_DTL
|
10 |
350 |
10
(0)| 00
:00:01 | ROWID | ROWID |
|* 5 |
INDEX RANGE SCAN
| IDX$$_21C0F0001
|
10 |
|
4
(0)| 00
:00:01 |
|
|
|* 6 |
TABLE ACCESS BY GLOBAL INDEX ROWID| PS_SCH_MNG_SCH_TBL |
13 |
884 |
9
(0)| 00
:00:01 | ROWID | ROWID |
|* 7 |
INDEX RANGE SCAN
| IDX$$_21C0F0002
|
13 |
|
3
(0)| 00
:00:01 |
|
|
--------------------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(TO_DATE(:4,'YYYY-MM-DD')&amp;lt;=TO_DATE(:5,'YYYY-MM-DD'))
3 - access(&amp;quot;A&amp;quot;.&amp;quot;EMPLID&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;EMPLID&amp;quot; AND &amp;qu
&amp;quot;A&amp;quot;.&amp;quot;SCH_PRIM_ALT_IND&amp;quot;=&amp;quot;M&amp;quot;.&amp;quot;SCH_PRIM_ALT_IND&a
SYS_OP_DESCEND(&amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;)=SYS_OP_DESCEND(&amp;quot;M&amp;quot;.&amp;quot;
5 - access(&amp;quot;A&amp;quot;.&amp;quot;EMPLID&amp;quot;=:1 AND &amp;quot;A&amp;quot;.&amp;quot;SEQNUM&amp;quot;=1 AN
ALT_IND&amp;quot;=:3 AND
&amp;quot;A&amp;quot;.&amp;quot;DUR&amp;quot;&amp;gt;=TO_DATE(:4,'YYYY-MM-DD') AND &amp;quot;A&amp;quot;.&amp
6 - filter(&amp;quot;M&amp;quot;.&amp;quot;SCH_PRIM_ALT_IND&amp;quot;=:3 AND &amp;quot;M&amp;quot;.&amp;quot;EMPL_RCD&am
7 - access(&amp;quot;M&amp;quot;.&amp;quot;EMPLID&amp;quot;=:1 AND &amp;quot;M&amp;quot;.&amp;quot;DUR&amp;quot;&amp;gt;
Y-MM-DD'))
------------------------------------------------------------------------------PL/SQL procedure successfully completed.

29/08/2015 12:26

Automatically running sql_advisor tasks from ADDM reports Oracl...

6 de 6

https://jhdba.wordpress.com/2009/11/12/automatically-running-sql_ad...

The routine above works well but I am happy to consider any changes or improvements.
PS If anybody knows how to use a code tag and not have those horrible green wraparound marks please let me know

You May Like

1.
3 Steps to
Become a Successful Trader a year
ago trading-for-newbies.com Trading
for Newbies (sponsored)
This entry was posted on November 12, 2009 at 8:29 am and is led under addm, Oracle, scripts. Tagged: addm, cron, oracle tuning, performance,
sql_advisor, tuning, tuning script. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your
own site.

2 Responses to Automatically running sql_advisor tasks from ADDM reports

1. Raj

jamadagni said

March 13, 2014 at 3:28 pm


Nice idea, In 11G, you perhaps can use sql below to directly pick SQLIDs identied by ADDM for tuning, thus reducing your number of scripts. It
may work in 10g too but I dont have a 10g DB.
with x as (select task_name tn from dba_advisor_tasks where task_id = (select max(t. task_id) from dba_advisor_tasks t,
dba_advisor_log l where t.task_id = l.task_id and t.advisor_name = 'ADDM' and l.status = 'COMPLETED'))
select task_Name,max(replace(regexp_substr(replace(message,' ',','),'[^,]+',1,5),'"')) as sql_id
/*,max(regexp_substr(replace(message,' ',','),'[^,]+',1,8)) as execs
,max(regexp_substr(replace(message,' ',','),'[^,]+',1,17)) as avg_ela */
from DBA_ADVISOR_RATIONALE, x where task_name = x.tn and message like 'SQL statement with SQL_ID%'
group by task_Name, rec_id, replace(message,' ',',')
The commented columns get you number of executions and averaged elapsed time as reported by ADDM.
Reply

John Hallas said


March 13, 2014 at 4:02 pm
Thanks Raj, I will look at that code but it is an old post now so is probably well out of date
Reply
PSU for 11.1.0.7.1
Problems with SGA being a multiple of 4Gb (and high cpu count)

Create a free website or blog at WordPress.com. | The Andreas09 Theme.


Follow

Follow Oracle DBA - A lifelong learning experience


Build a website with WordPress.com

29/08/2015 12:26