Search notes:

Oracle: Introduction to AWR of 2014-11-03

What is the «traced» session's identifier?
select sid, serial# from v$session where sid = sys_context('USERENV', 'SID');
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/010_my_sid.sql
Repeatedly show other session's SQL statement:
--
--    Display «other» session's currently running
--    SQL statement.
--
select
  sql.sql_id,
  sql.executions,
  sql.cpu_time      / 1e6 cpu_time,
  sql.elapsed_time  / 1e6 elapsed_time,
  substr(sql.sql_text, 1, 100) text
from
  v$session ses left join
  v$sqlarea sql on ses.sql_address    = sql.address and
                   ses.sql_hash_value = sql.hash_value
where
  ses.sid = &1;
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/020_monitor_sql.sql
A statement that (hopefully for this presentation) takes longer than 10 seconds:
set timing on

select
  count(*)
from
  dba_objects,
  dba_objects
where
  rownum < 40e6;

set timing off
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/021a_ca_10_sek.sql
Another statement hat (hopefully) takes longer 10 seconds:
--
--  An SQL statement that takes a while to finish.
--
--  Note how SQL_ID changes when SQL changes.
--
set timing on

select
  avg(kurs)
from
  bewertungvalor
where
--IT:
--  stichtag between date '2011-01-01' and date '2011-03-22' and
--66er:
    stichtag between 
               date '2013-01-01' and 
               date '2013-02-10' 
    and kurs > 1000;

set timing off
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/021_ca_10_sek.sql
Find actual execution time in v$sqlarea:
--
--  SQL Statements are cached in v$sqlarea.
--  -> executions is incremented when SQL executed
--  -> cpu_time and elapsed_time are cumulative in micro-secs
--     hence / 1e6
--
select
  executions           executions,
  cpu_time     / 1e6   cpu_time,
  elapsed_time / 1e6   elapsed_time
from
  v$sqlarea
where
  sql_id = '&1';
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/022_time_of_sql.sql
But taking such statistics are already automated:
--
--  Wouldn't it be nice if all this were automated...
--
--  ASH = Active Session History
--
--  2MB memory per CPU reserved for collected data

select
  pool,
  bytes/1024/1024 "Size in MB"
from
  v$sgastat
where
  name = 'ASH buffers';

-- Compare
--   select cpu_count_current from v$license;
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/030_ash_sgastat.sql
Find snapshot IDs:
--
--   Find oldest and most recent timestamp of
--   such gathered statements.
--
--   Oldest records are purged from memory when
--   SQL activity writes new records.
--
select
  to_char(min(sample_time), 'dd.mm.yyyy hh24:mi:ss') min_time,
  to_char(max(sample_time), 'dd.mm.yyyy hh24:mi:ss') max_time,
  count(*)                                           cnt
from
  v$active_session_history;
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/040_ash_min_max_sample_time.sql
Show samples in development/databases/Oracle/installed/dynamic-performance-views/active/session_history:
--
--   One sample per second IF there is activity (note
--   the gaps in a session).
--
select * from (
--
   select
     to_char(hist.sample_time, 'hh24:mi:ss') || '| ' sample_time,
     replace(cast(sql.sql_fulltext as varchar2(100)), chr(10), ' '),
     '|' || hist.sql_id "SQL Id",
     '|' || to_char(hist.sql_exec_start, 'hh24:mi:ss') "Start",
     hist.is_awr_sample  -- <== Note particularly this column!
--   hist.session_id, -- {
--   hist.session_serial#, -- }
--   delta_time / 1e6      delta_s, {
--   hist.tm_delta_time,
--   hist.tm_delta_cpu_time,
--   hist.tm_delta_db_time,
   --hist.event ,
     /*,
     hist.p1text,
     hist.p1,
     hist.p2text,
     hist.p2,
     hist.p3text,
     hist.p3, */
     --
   --hist.current_obj#,
   --hist.current_file#,
   --hist.current_block#,
     --
   --hist.time_waited -- }
   , time_waited
   from
     v$active_session_history hist left join
     -- Join with sqlarea to get sql text.
     v$sqlarea                sql on hist.sql_id = sql.sql_id
   where
     session_id      = &1 and -- <== Indicate session_id and
     session_serial# = &2     -- <== serial#
   order by
     sample_time desc
--
)
where
  rownum < 5000
order by
  sample_time
;
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/050_ash_history.sql
Find «top» SQL statement:
--
--   How many seconds is spent for each SQL statement
--
select
  top.sql_id,
  top.cnt,
  top.pct,
  replace(cast(substr(sql.sql_fulltext, 1, 100) as varchar2(100)), chr(10), '') text
from (
  select
    sql_id,
    count(*) cnt,
    to_char(ratio_to_report(count(*)) over () * 100, '90.99') pct,
    row_number() over (order by count(*) desc) r
  from
    v$active_session_history
  where
    session_type <> 'BACKGROUND'  and
    sample_time   > sysdate - 20/24/60 -- Last twenty minutes
  group by
    sql_id
  order by
    count(*) desc
) top left join
v$sqlarea sql on top.sql_id = sql.sql_id
where
  top.r < 50 
order by
  top.cnt desc
;
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/060_ash_top_sql.sql
Automatic flushing of v$active_session_history into dba_hist_active_sess_history.
--
--  v$active_session_history is flushed every
--  hour or when 66%(?) full.
--
--  Only records where is_awr_sample = 'Y'
--

select
  snap_id,
  to_char(sample_time, 'dd.mm.yyyy hh24:mi:ss') sample_time,
  session_serial#,
  sql_id,
  sql_exec_start,
  time_waited
from
  dba_hist_active_sess_history
where
  session_id      = &1 and
  session_serial# = &2
order by
  sample_time;
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/100_dba_hist_active_sess_history.sql
Find minimum and maximum sample time in dba_hist_active_sess_history:
select
  to_char(min(sample_time), 'dd-mm-yyyy hh24:mi:ss') "Min sample time",
  to_char(max(sample_time), 'dd-mm-yyyy hh24:mi:ss') "Max sample time",
  count(*)
from
  dba_hist_active_sess_history;
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/110_dba_hist_min_max_sample_time.sql
Create a snapshot:
begin
  dbms_workload_repository.create_snapshot();
end;
/
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/120_create_snapshot.sql
Show snapshots:
select
  snap_id,
  dbid,
  instance_number I,
  '|' || to_char(startup_time       , 'dd.mm.yyyy hh24:mi:ss'),
  '|' || to_char(begin_interval_time, 'dd.mm.yyyy hh24:mi:ss'),
  '|' || to_char(end_interval_time  , 'dd.mm.yyyy hh24:mi:ss'),
--snap_level, -- ?
  snap_flag, -- 0: Automatic, 1. Manually, 2: Imported
  flush_elapsed -- How long did it take to take snapshot
from
  dba_hist_snapshot
order by
  begin_interval_time;
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/130_snapshots.sql
Show available AWR statistics in a given period
--
--   https://raw.githubusercontent.com/ReneNyffenegger/oracle_scriptlets/master/ash-awr/stats_in_period.sql
--
select
   stat.sql_id                                                                            sql_id,
   replace (cast (dbms_lob.substr (text.sql_text, 100) as varchar (100)), chr (10), '')   sql_text,
   --
   executions                                                                             executions,
   --
   round(elapsed_time                                / 1000000  , 3)                      seconds_elapsed,
   round(cpu_time                                    / 1000000  , 3)                      seconds_cpu_elapsed,
   --
   round(elapsed_time / executions                   / 1000000  , 3)                      seconds_elapsed_per_exec,
   round(cpu_time     / executions                   / 1000000  , 3)                      seconds_cpu_elapsed_per_exec,
   round(iowait_time  / executions                   / 1000000  , 3)                      seconds_iowait_ela_per_exec,
   --
   disk_reads                                                                             disk_reads,
   buffer_gets                                                                            buffer_gets,
   writes                                                                                 writes,
   parses                                                                                 parses,
   sorts                                                                                  sorts
from
    ( select  --- {
               stat.sql_id                     sql_id,
          sum (stat.executions_delta    )      executions,
          sum (stat.elapsed_time_delta  )      elapsed_time,
          sum (stat.cpu_time_delta      )      cpu_time,
          sum (stat.iowait_delta        )      iowait_time,
          sum (stat.disk_reads_delta    )      disk_reads,
          sum (stat.buffer_gets_delta   )      buffer_gets,
          sum (stat.direct_writes_delta )      writes,
          sum (stat.parse_calls_delta   )      parses,
          sum (stat.sorts_delta         )      sorts
      from
          dba_hist_sqlstat   stat where snap_id in (
                                        ------------- See script find_snap_ids.sql
                                           select snap_id from dba_hist_ash_snapshot
                                           where
                                             end_interval_time   > sysdate - 3/24 and    -- first snap
                                             begin_interval_time < sysdate               -- last snap
                                        -------------
                                  )
      group by
          stat.sql_id
    )                       stat  --- }
    join dba_hist_sqltext   text on stat.sql_id = text.sql_id
where
    executions > 0
order by
    seconds_elapsed desc;
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/200_awr_stats_in_period.sql
Execute a few SQL statements. Which one took most time to execute?
--
--  A procedure that takes a while to run...
--  which SQL statement contributes most to
--  spent time?
--
set timing on

declare

  start_time  date;

begin

  start_time := sysdate;

  <<ONE_MINUTE>> while true loop

     for valor in (
       select valorennr, valorenzusatznr 
         from valorgattung
     ) loop
     
       if start_time +  1 * 1/24/60 < sysdate then
          exit ONE_MINUTE;
       end if;

       ------------------------------------------------------------
       declare
         r bewertungvalor%rowtype;
       begin

       -- 407918886kfkv

         select * into r from bewertungvalor
          where valorennr       = valor.valorennr and
                valorenzusatznr = valor.valorenzusatznr and 
                stichtag        = date '2012-12-20';

       exception
         when no_data_found or 
              too_many_rows then

              null;
       end;

       ------------------------------------------------------------

/*
       declare
         r bewertungvalor%rowtype;
       begin

         execute immediate 'select * from bewertungvalor ' ||
         'where valorennr       = ''' || valor.valorennr || ''' and ' ||
               'valorenzusatznr = ''' || valor.valorenzusatznr || ''' and ' ||
               'stichtag = date ''2012-12-20'' ' into r;

       exception
         when no_data_found or 
              too_many_rows then

              null;
       end;
*/

       ------------------------------------------------------------

       declare
         r valorenkurs%rowtype;
       begin

         select * into r from valorenkurs
          where valorennr       = valor.valorennr and
                valorenzusatznr = valor.valorenzusatznr and
                gueltigabdatum  = date '2012-12-20';

       exception
         when no_data_found or 
              too_many_rows then

              null;

       end;


     end loop;

  end loop;

end;
/
Github repository oracle_scriptlets, path: /ash-awr/Introduction-Nov-3rd-14/300_generate_selects.sql

See also

Automatic Workload Repository

Index