This is a quick post to share a SQL statement I use a lot at work. The query mines the AWR tables (beware the licence implications) for a specific SQL ID and date/time range and shows a few choice statistics for each snapshot period.
awrsql.sql:
prompt enter start and end times in format DD-MON-YYYY [HH24:MI] column sample_end format a21 select to_char(min(s.end_interval_time),'DD-MON-YYYY DY HH24:MI') sample_end , q.sql_id , q.plan_hash_value , sum(q.EXECUTIONS_DELTA) executions , round(sum(DISK_READS_delta)/greatest(sum(executions_delta),1),1) pio_per_exec , round(sum(BUFFER_GETS_delta)/greatest(sum(executions_delta),1),1) lio_per_exec , round((sum(ELAPSED_TIME_delta)/greatest(sum(executions_delta),1)/1000),1) msec_exec from dba_hist_sqlstat q, dba_hist_snapshot s where q.SQL_ID=trim('&sqlid.') and s.snap_id = q.snap_id and s.dbid = q.dbid and s.instance_number = q.instance_number and s.end_interval_time >= to_date(trim('&start_time.'),'dd-mon-yyyy hh24:mi') and s.begin_interval_time <= to_date(trim('&end_time.'),'dd-mon-yyyy hh24:mi') and substr(to_char(s.end_interval_time,'DD-MON-YYYY DY HH24:MI'),13,2) like '%&hr24_filter.%' group by s.snap_id , q.sql_id , q.plan_hash_value order by s.snap_id, q.sql_id, q.plan_hash_value /
Nothing ground breaking and I’m sure many will have a similar script.
Below I have example output showing one of the scripts many successful outings, quite a dramatic plan change I’m sure you’ll agree.
SQL> @awrsql enter start and end times in format DD-MON-YYYY [HH24:MI] Enter value for sqlid: 1jjpo2i4b313g Enter value for start_time: 15-NOV-2011 Enter value for end_time: 21-NOV-2011 13:00 Enter value for hr24_filter: SAMPLE_END SQL_ID PLAN_HASH_VALUE EXECUTIONS PIO_PER_EXEC LIO_PER_EXEC MSEC_EXEC --------------------- ------------- --------------- ---------- ------------ ------------ ---------- 15-nov-2011 TUE 08:00 1jjpo2i4b313g 3133159894 129629 0 5 0 16-nov-2011 WED 08:01 1jjpo2i4b313g 3133159894 115003 0 5 .1 17-nov-2011 THU 08:01 1jjpo2i4b313g 3133159894 115741 0 5 0 18-nov-2011 FRI 07:00 1jjpo2i4b313g 3133159894 30997 0 5 .1 18-nov-2011 FRI 08:00 1jjpo2i4b313g 3133159894 81034 0 5 0 21-nov-2011 MON 00:00 1jjpo2i4b313g 790865878 16 323091.6 323128.3 36905.8 21-nov-2011 MON 01:00 1jjpo2i4b313g 790865878 29 349676.2 349713.7 48387.2 21-nov-2011 MON 02:00 1jjpo2i4b313g 790865878 35 339474.6 339509.2 34057.7 21-nov-2011 MON 03:00 1jjpo2i4b313g 790865878 37 340934.6 340970.2 35899.4 21-nov-2011 MON 04:01 1jjpo2i4b313g 790865878 38 333469.1 333503.9 35450.8 21-nov-2011 MON 05:00 1jjpo2i4b313g 790865878 35 347559.3 347595.2 35231.8 21-nov-2011 MON 06:00 1jjpo2i4b313g 790865878 32 340224.8 340260 35208.3
I also like to use the query to track number of executions or LIO per execution over a longer time frame to see if either the frequency or individual impact of the SQL is changing over time. I can use the “hr24_filter” variable to do this, for example showing me all snapshots for hour “13” over a whole month.
Good One.Thanks for sharing 🙂
Thanks Anand
It’s bit confusing to see the results of that report if one long execution (with single SQL_EXEC_ID) is spanned across multiple AWR snapshots 🙂
Hi Alex,
You are correct, the executions column will show zero for snapshots in which the SQL did not complete. This can be confusing. I suspect there are similar and better variations out there – however this one still serves me well in most cases.
Thanks
Excellent! Thanks!
Thanks for sharing the query.Can i know the reason behind using the function greatest in this query
round(sum(DISK_READS_delta)/greatest(sum(executions_delta),1),1) pio_per_exec
Hi, thanks for the comment. The purpose of the GREATEST() function is to handle executions_delta = 0. This can happen if the query is still executing.