Search This Blog

Total Pageviews

Saturday, 12 August 2023

TOP SQL reporting

TOP SQL reporting


TOP SQL reporting

---- mon_topsql.sql 


https://github.com/vishaldesai/Oracle_Scripts/blob/master/Exadata/mon_topsql.sql

-- Author:      Tanel Poder ( http://blog.tanelpoder.com | tanel@tanelpoder.com )





SET LINES 999 PAGES 5000 TRIMSPOOL ON TRIMOUT ON TAB OFF 

COL pct FOR A10 JUST RIGHT
COL cpu_pct FOR 999.9
COL io_pct FOR 999.9
col OWNER for a20
col OBJECT_NAME    for a20                                                                                                                   
col PROCEDURE_NAME for a20 

BREAK ON day SKIP 1

DEF days=1

PROMPT Displaying daily top SQL for last &days days...

WITH ash AS (
    SELECT 
        day
      , owner
      , object_name
      , procedure_name
      , sql_id
      , sql_plan_hash_value
      , total_seconds
      , io_seconds
      , cpu_seconds
      , LPAD(TRIM(TO_CHAR(RATIO_TO_REPORT(total_seconds) OVER (PARTITION BY day) * 100, '999.9'))||'%', 10) pct
      , RATIO_TO_REPORT(total_seconds) OVER (PARTITION BY day) * 100 pct_num
    FROM (
        SELECT
            TO_CHAR(sample_time, 'YYYY-MM-DD') day
          , sql_id
          , sql_plan_hash_value 
          , p.owner
          , p.object_name
          , p.procedure_name
          , SUM(10) total_seconds
          , SUM(CASE WHEN wait_class = 'User I/O' THEN 10 ELSE 0 END) io_seconds
          , SUM(CASE WHEN wait_class IS NULL THEN 10 ELSE 0 END) cpu_seconds
        FROM
            dba_hist_active_sess_history a
          , dba_procedures p
        WHERE
            a.plsql_entry_object_id = p.object_id (+)
        AND a.plsql_entry_subprogram_id = p.subprogram_id (+)
        AND sample_time > SYSDATE - &days
        AND session_type != 'BACKGROUND' -- ignore for now
        GROUP BY
            sql_id
          , sql_plan_hash_value 
          , p.owner
          , p.object_name
          , p.procedure_name
          , TO_CHAR(sample_time, 'YYYY-MM-DD')
    )
)
, sqlstat AS (
    SELECT /*+ MATERIALIZE */ 
        TO_CHAR(begin_interval_time, 'YYYY-MM-DD') day
      , sql_id
      , plan_hash_value
      , SUM(executions_delta) executions
      , SUM(rows_processed_delta) rows_processed
      , SUM(disk_reads_delta) blocks_read
      , SUM(disk_reads_delta)*8/1024 mb_read
      , SUM(buffer_gets_delta) buffer_gets
      , SUM(iowait_delta)/1000000 awr_iowait_seconds
      , SUM(cpu_time_delta)/1000000 awr_cpu_seconds 
      , SUM(elapsed_time_delta)/1000000 awr_elapsed_seconds
    FROM
        dba_hist_snapshot
      NATURAL JOIN
        dba_hist_sqlstat
    WHERE
        begin_interval_time > SYSDATE - &days
    GROUP BY
        TO_CHAR(begin_interval_time, 'YYYY-MM-DD') 
      , sql_id
      , plan_hash_value
)
SELECT /*+ MONITOR */
        day
      , pct
      , owner
      , object_name
      , procedure_name
      , sql_id
      , sql_plan_hash_value plan_hash
      , ROUND(total_seconds / 3600,1) total_hours
      , total_seconds
      , executions
      , ROUND(total_seconds / NULLIF(executions,0),2) seconds_per_exec
      , io_pct
      , cpu_pct
      , mb_read
      , ROUND(mb_read / NULLIF(executions,0),2) mb_per_exec
      , buffer_gets
      , ROUND(buffer_gets / NULLIF(executions,0),2) bufget_per_exec
      , CASE WHEN sql_id IS NOT NULL THEN 
            'SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('''||sql_id||''','||CASE WHEN sql_plan_hash_value = 0 THEN 'NULL' ELSE TO_CHAR(sql_plan_hash_value) END||', format=>''ADVANCED''));'
        END extract_plan_from_awr
FROM (
    SELECT
        day
      , pct
      , owner
      , object_name
      , procedure_name
      , sql_id
      , sql_plan_hash_value
      , total_seconds
      , io_seconds/total_seconds*100 io_pct
      , cpu_seconds/total_seconds*100 cpu_pct
      , (SELECT executions FROM sqlstat s  WHERE ash.sql_id = s.sql_id AND ash.sql_plan_hash_value = s.plan_hash_value AND ash.day = s.day) executions
      , (SELECT mb_read FROM sqlstat s     WHERE ash.sql_id = s.sql_id AND ash.sql_plan_hash_value = s.plan_hash_value AND ash.day = s.day) mb_read
      , (SELECT buffer_gets FROM sqlstat s WHERE ash.sql_id = s.sql_id AND ash.sql_plan_hash_value = s.plan_hash_value AND ash.day = s.day) buffer_gets
    FROM 
        ash
    WHERE 
        ash.pct_num >= 1
)
ORDER BY
    day DESC
  , total_seconds DESC
/




DAY               PCT OWNER                OBJECT_NAME          PROCEDURE_NAME       SQL_ID         PLAN_HASH TOTAL_HOURS TOTAL_SECONDS EXECUTIONS SECONDS_PER_EXEC IO_PCT CPU_PCT    MB_READ MB_PER_EXEC BUFFER_GETS BUFGET_PER_EXEC EXTRACT_PLAN_FROM_AWR
---------- ---------- -------------------- -------------------- -------------------- ------------- ---------- ----------- ------------- ---------- ---------------- ------ ------- ---------- ----------- ----------- --------------- --------------------------------------------------------------------------------------------------------------------------
2023-08-12      78.6%                                                                ctyc1af1abg5u  200298931          91        327510                                 .0   100.0                                                    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('ctyc1af1abg5u',200298931, format=>'ADVANCED'));
                 4.4%                                                                                       0         5.1         18340                               22.3    72.7
                 4.2%                                                                3xjw1ncw5vh27 2487977020         4.9         17500                               88.3    11.7                                                    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('3xjw1ncw5vh27',2487977020, format=>'ADVANCED'));
                 4.2%                                                                c7ngymcfjtb1c 1658157256         4.8         17450                               43.8    56.2                                                    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('c7ngymcfjtb1c',1658157256, format=>'ADVANCED'));

2023-08-11      55.1%                                                                ctyc1af1abg5u  200298931        55.9        201130                                 .0   100.0                                                    SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('ctyc1af1abg5u',200298931, format=>'ADVANCED'));




                 8.7%                                                                1zuyhdtsmmx5s 3008400300         8.8         31680    





define sql_id='ctyc1af1abg5u'

SET TERMOUT OFF pagesize 5000 tab off verify off linesize 999 trimspool on trimout on null ""
SET TERMOUT ON


COL exec_per_sec    FOR 99999990
COL ela_ms_per_sec  FOR 99999990
COL rows_per_sec    FOR 99999990
COL lios_per_sec    FOR 99999990
COL blkrd_per_sec   FOR 99999990
COL cpu_ms_per_sec  FOR 99999990
COL iow_ms_per_sec  FOR 99999990
COL clw_ms_per_sec  FOR 99999990
COL apw_ms_per_sec  FOR 99999990
COL ccw_ms_per_sec  FOR 99999990


SELECT
    CAST(begin_interval_time AS DATE) begin_interval_time
,st.con_id
  , sql_id
  , plan_hash_value
  , ROUND(SUM(executions_delta    )        / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) exec_per_sec
  , ROUND(SUM(elapsed_time_delta  ) / 1000 / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) ela_ms_per_sec
  , ROUND(SUM(rows_processed_delta)        / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) rows_per_sec
  , ROUND(SUM(buffer_gets_delta   )        / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) lios_per_sec
  , ROUND(SUM(disk_reads_delta    )        / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) blkrd_per_sec
  , ROUND(SUM(cpu_time_delta      ) / 1000 / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) cpu_ms_per_sec
  , ROUND(SUM(iowait_delta        ) / 1000 / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) iow_ms_per_sec
  , ROUND(SUM(clwait_delta        ) / 1000 / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) clw_ms_per_sec
  , ROUND(SUM(apwait_delta        ) / 1000 / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) apw_ms_per_sec
  , ROUND(SUM(ccwait_delta        ) / 1000 / ((CAST(end_interval_time AS DATE) - CAST(begin_interval_time AS DATE)) * 86400), 1) ccw_ms_per_sec
FROM
    dba_hist_snapshot sn
  , dba_hist_sqlstat st
WHERE
    sn.snap_id = st.snap_id
AND sn.dbid    = st.dbid
AND sn.instance_number = st.instance_number
AND sql_id = '&sql_id'
--AND plan_hash_value LIKE '2'
--AND begin_interval_time >= 3
--AND end_interval_time   <= 4
-- AND begin_interval_time > sysdate -1
GROUP BY
    CAST(begin_interval_time AS DATE)
,st.con_id
  , CAST(end_interval_time AS DATE)
  , sql_id
  , plan_hash_value
ORDER BY
    begin_interval_time
  , sql_id
  , plan_hash_value
/           


SET LINESIZE 200 PAGESIZE 200 TRIMSPOOL ON COLUMN username FORMAT a20 COLUMN total_WaitTime FORMAT 999,999.99 HEADING "WAIT_SEC" COLUMN comment FORMAT a30 COLUMN inst_id FORMAT 9999 COLUMN sid FORMAT 999999 col kill for a17 col EVENT for a20 SELECT t.*, CASE WHEN ROWNUM <= 5 THEN 'Highest wait: ' || t.username || ' with ' || t.total_WaitTime || ' seconds' ELSE 'Waits by user last 15 minutes' END AS "comment" FROM ( SELECT ''''||s.sid ||','|| s.serial#||',@'||s.inst_id ||'''' kill, --s.inst_id, -- s.sid, s.con_id, s.username, SUM(ash.wait_time + ash.time_waited) / 1000000 AS total_WaitTime, s.sql_id, s.event FROM gv$active_session_history ash JOIN gv$session s ON ash.session_id = s.sid AND ash.inst_id = s.inst_id WHERE 1=1 -- ash.sample_time > (SYSDATE - 1/96) -- Last 15 minutes and ash.sample_time > SYSDATE - INTERVAL '15' MINUTE AND s.username IS NOT NULL GROUP BY ''''||s.sid ||','|| s.serial#||',@'||s.inst_id ||'''',s.con_id, s.username,s.sql_id,s.event ORDER BY 4 DESC ) t WHERE ROWNUM < 20; from https://www.pythian.com/blog/recent-spike-report-from-vactive_session_history-ash AVG — the average “load” (active sessions) over a 5-minute interval. This should help you spot a problem when you scroll through the results. TOT — total “load” (active sessions) for that sample time. RAC users: each RAC node will have its own sample time, within 1 second of each other, but not exactly spot-on. So, even if you have sessions waiting on the same event, they will not be grouped together. I kind of like it this way, for now. SAMPLE_TIME — self-explanatory CNT — the number of active sessions waiting on the same event and query EVENT — the event been waited on SQL_TEXT — self-explanatory, except when empty which means either not found in shared pool or not available in ASH SQL_ID — if you need to find the SQL CHD — the child number being executed COLUMN event FORMAT a25 TRUNCATED COLUMN "SUBSTR(SQ.SQL_TEXT,1)" FORMAT a40 HEADING "SQL_TEXT" TRUNCATED col SAMPLE_TIME for a25 -- Metric Columns COLUMN "sec p" FORMAT a15 COLUMN "disk p" FORMAT 999,999 COLUMN "gets p" FORMAT 9,999,999 COLUMN "rows p" FORMAT 999,999 COLUMN "cpu p" FORMAT 99.999 COLUMN exec FORMAT 999,999,999 COLUMN open FORMAT 999 COLUMN e FORMAT 999 col SQL_TEXT for a50 set linesize 300 pagesize 300 SELECT ROUND(AVG(MAX(cnt_tot)) OVER (ORDER BY sample_time RANGE BETWEEN INTERVAL '5' MINUTE PRECEDING AND CURRENT ROW)) AS avg, MAX(cnt_tot) AS tot, sample_time, MAX(cnt) AS cnt, event, SUBSTR(sq.sql_text, 1, 100) as sql_text, -- Truncated for display ash.sql_id, ash.sql_child_number AS chd, TO_CHAR(ROUND(SUM(elapsed_time) / NULLIF(SUM(executions), 0) / 1000000, 6), '9,990.999999') AS "sec p", ROUND(SUM(disk_reads) / NULLIF(SUM(executions), 0), 0) AS "disk p", ROUND(SUM(buffer_gets) / NULLIF(SUM(executions), 0), 0) AS "gets p", ROUND(SUM(rows_processed) / NULLIF(SUM(executions), 0), 0) AS "rows p", ROUND(SUM(cpu_time) / 1000000 / NULLIF(SUM(executions), 0), 3) AS "cpu p", SUM(executions) AS exec, SUM(users_opening) AS open, SUM(users_executing) AS e FROM ( SELECT SUM(COUNT(*)) OVER (PARTITION BY sample_time) AS cnt_tot, COUNT(*) AS cnt, sample_time, event, sql_id, sql_child_number FROM gv$active_session_history WHERE sample_time > SYSDATE - INTERVAL '1' HOUR GROUP BY event, sql_id, sql_child_number, sample_time HAVING COUNT(*) >= 10 ) ash LEFT JOIN gv$sql sq ON ash.sql_id = sq.sql_id AND ash.sql_child_number = sq.child_number GROUP BY event, sql_text, ash.sql_id, ash.sql_child_number, ash.sample_time ORDER BY sample_time DESC;
connnect to pdbs col PLAN_TABLE_OUTPUT for a150 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('ctyc1af1abg5u',200298931, format=>'ADVANCED'));

Oracle DBA

anuj blog Archive