Developer ToolsFree generatorPDF, Excel, Word exportOracle Database

Oracle Database 19c AWR Report and Top SQL Generator

This generator writes a SQL*Plus script for Oracle Database 19c that finds the AWR snapshots for a time window, spools the AWR HTML report, lists the top SQL by elapsed time, shows the largest segments in an ERP schema and reports monthly used space growth. Fill in the window, instance, top N and schema owner, then copy and run.

Fill in

For example CRPDTA (JD Edwards), APPS or a product schema such as INV (E-Business Suite), SYSADM (PeopleSoft).

Generated code
Download:

1. Find the snapshot range for the window

-- Run in SQL*Plus as a user with SELECT on DBA_HIST views. Requires the Diagnostics Pack licence.
SET LINESIZE 200 PAGESIZE 100 VERIFY OFF
COLUMN dbid NEW_VALUE dbid
COLUMN bid NEW_VALUE bid
COLUMN eid NEW_VALUE eid

SELECT dbid FROM v$database;

SELECT snap_id, begin_interval_time, end_interval_time, startup_time
FROM   dba_hist_snapshot
WHERE  dbid = &dbid
AND    instance_number = 1
AND    end_interval_time BETWEEN TO_TIMESTAMP('2026-10-20 08:00', 'YYYY-MM-DD HH24:MI')
                             AND TO_TIMESTAMP('2026-10-20 12:00', 'YYYY-MM-DD HH24:MI')
ORDER  BY snap_id;

SELECT MIN(snap_id) bid, MAX(snap_id) eid
FROM   dba_hist_snapshot
WHERE  dbid = &dbid
AND    instance_number = 1
AND    end_interval_time BETWEEN TO_TIMESTAMP('2026-10-20 08:00', 'YYYY-MM-DD HH24:MI')
                             AND TO_TIMESTAMP('2026-10-20 12:00', 'YYYY-MM-DD HH24:MI');

2. AWR HTML report for the range

SET PAGESIZE 0 LINESIZE 8000 HEADING OFF FEEDBACK OFF TRIMSPOOL ON
SPOOL awr_1_&bid._&eid..html
SELECT output
FROM   TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML(&dbid, 1, &bid, &eid));
SPOOL OFF
SET PAGESIZE 100 LINESIZE 200 HEADING ON FEEDBACK ON

-- Interactive alternative: @?/rdbms/admin/awrrpt.sql (RAC wide: @?/rdbms/admin/awrgrpt.sql)

3. Top SQL by elapsed time in the range

WITH s AS (
  SELECT sql_id,
         SUM(executions_delta)   execs,
         SUM(elapsed_time_delta) ela_us,
         SUM(cpu_time_delta)     cpu_us,
         SUM(buffer_gets_delta)  gets,
         SUM(disk_reads_delta)   reads
  FROM   dba_hist_sqlstat
  WHERE  dbid = &dbid
  AND    instance_number = 1
  AND    snap_id > &bid
  AND    snap_id <= &eid
  GROUP  BY sql_id
  ORDER  BY SUM(elapsed_time_delta) DESC
  FETCH FIRST 10 ROWS ONLY
)
SELECT s.sql_id,
       s.execs,
       ROUND(s.ela_us / 1e6, 1)                           elapsed_s,
       ROUND(s.cpu_us / 1e6, 1)                           cpu_s,
       ROUND(s.ela_us / 1e6 / NULLIF(s.execs, 0), 3)      s_per_exec,
       s.gets,
       s.reads,
       DBMS_LOB.SUBSTR(t.sql_text, 120, 1)                sql_text
FROM   s
LEFT JOIN dba_hist_sqltext t
       ON t.dbid = &dbid AND t.sql_id = s.sql_id
ORDER  BY s.ela_us DESC;

4. Largest segments for the schema

SELECT segment_name,
       segment_type,
       tablespace_name,
       ROUND(SUM(bytes) / 1024 / 1024 / 1024, 2) size_gb
FROM   dba_segments
WHERE  owner = UPPER('CRPDTA')
GROUP  BY segment_name, segment_type, tablespace_name
ORDER  BY SUM(bytes) DESC
FETCH FIRST 10 ROWS ONLY;

5. Monthly used space growth from AWR

-- tablespace_usedsize is in database blocks; convert with the tablespace block size.
WITH u AS (
  SELECT TRUNC(CAST(sn.end_interval_time AS DATE), 'MM') mon,
         ts.name                                           tablespace_name,
         MAX(us.tablespace_usedsize * dt.block_size)       used_bytes
  FROM   dba_hist_tbspc_space_usage us
  JOIN   dba_hist_snapshot sn
         ON sn.snap_id = us.snap_id
        AND sn.dbid = us.dbid
        AND sn.instance_number = 1
  JOIN   v$tablespace ts
         ON ts.ts# = us.tablespace_id
  JOIN   dba_tablespaces dt
         ON dt.tablespace_name = ts.name
  WHERE  us.dbid = &dbid
  GROUP  BY TRUNC(CAST(sn.end_interval_time AS DATE), 'MM'), ts.name
)
SELECT mon,
       ROUND(SUM(used_bytes) / 1024 / 1024 / 1024, 2) used_gb,
       ROUND((SUM(used_bytes) - LAG(SUM(used_bytes)) OVER (ORDER BY mon)) / 1024 / 1024 / 1024, 2) growth_gb
FROM   u
GROUP  BY mon
ORDER  BY mon;

AWR and all DBA_HIST views require the Oracle Diagnostics Pack (Enterprise Edition); check CONTROL_MANAGEMENT_PACK_ACCESS and your licence before running. On Standard Edition 2 use Statspack (spreport.sql) instead. Snapshot ranges must not span an instance restart (compare STARTUP_TIME). Default AWR retention is 8 days, so monthly growth needs a longer retention set with DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS. In a multitenant database, run from the container whose AWR data you want and verify which snapshots DBA_HIST views return there (12.2 and later also provide AWR_ROOT_ and AWR_PDB_ views).

Send us an AWR report

Share an AWR report from your slow ERP window and we will return the top three findings with the SQL_IDs and the likely fix for each.

Optional. The tool and every export work without this. No spam.

Was this tool useful?

How to use it

Enter the window as YYYY-MM-DD HH24:MI, for example the hours when MRP or the period close ran slowly, plus the instance number, how many rows you want and the ERP schema owner: CRPDTA or PRODDTA for JD Edwards business data, SYSADM for PeopleSoft, or a product schema such as INV or GL for E-Business Suite (APPS owns code and synonyms, not most tables). Run the script in SQL*Plus or SQLcl. Step 1 captures DBID and the first and last snapshot into substitution variables with COLUMN NEW_VALUE, so the later steps reuse them without editing.

  • Step 2 writes awr_<inst>_<bid>_<eid>.html in the current directory.
  • Step 3 sums *_DELTA columns for snapshots after bid up to eid, matching the AWR report interval.
  • Elapsed and CPU time in DBA_HIST_SQLSTAT are in microseconds.

Where the data comes from

DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML takes DBID, instance number, begin snapshot and end snapshot (plus an optional options argument) and returns the report as rows in an OUTPUT column, which is why it is wrapped in TABLE(). DBA_HIST_SNAPSHOT holds the snapshot intervals, DBA_HIST_SQLSTAT holds per snapshot statistics per SQL_ID and plan, and DBA_HIST_SQLTEXT holds the full statement as a CLOB. DBA_HIST_TBSPC_SPACE_USAGE records tablespace size and used size in blocks per snapshot, keyed by TABLESPACE_ID, which joins to TS# in V$TABLESPACE.

Reading the results

In the AWR report start with Top 10 Foreground Events and Load Profile, then the SQL ordered by Elapsed Time section. Compare the top SQL query output with it: a statement with high seconds per execution is a plan or design problem, while one with tiny seconds per execution but huge execution counts is a call pattern problem, common with ERP row by row processing. For each SQL_ID, look at plan history with SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('sql_id')) to see if a plan changed. Growth figures per month feed directly into storage and backup planning.

Licensing and version gotchas

Querying any DBA_HIST view or running AWR reports uses the Diagnostics Pack, which is an extra cost option on Enterprise Edition and not available on Standard Edition 2. If CONTROL_MANAGEMENT_PACK_ACCESS is NONE, snapshots are not collected. On SE2 install Statspack (spcreate.sql) and report with spreport.sql. FETCH FIRST n ROWS ONLY needs 12c or later, which 19c is. Default retention is 8 days with hourly snapshots, so monthly growth needs retention changed weeks in advance.

Frequently Asked Questions

How do I generate an AWR report in Oracle 19c?

Interactively run @?/rdbms/admin/awrrpt.sql in SQL*Plus and answer the prompts for format, days and snapshot IDs. For scripting, call DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML(dbid, instance, begin_snap, end_snap) inside TABLE() and spool the OUTPUT column to an .html file, as this generator does.

How do I check table size in an Oracle 19c database?

Query DBA_SEGMENTS: SUM(bytes) grouped by segment_name and segment_type for the owner. Indexes and LOB segments are separate segments, so a table's full footprint includes its indexes (DBA_INDEXES) and LOBs (DBA_LOBS segment names). Partitioned tables have one segment per partition, which the grouping sums.

How do I make a monthly database growth report in Oracle?

Use DBA_HIST_TBSPC_SPACE_USAGE joined to DBA_HIST_SNAPSHOT, convert TABLESPACE_USEDSIZE from blocks to bytes with the tablespace block size, take the maximum per month and compare with the previous month using LAG. AWR retention must cover the months you want, and the Diagnostics Pack must be licensed.

Do I need a licence to query DBA_HIST views?

Yes. AWR, ASH and the DBA_HIST views belong to the Oracle Diagnostics Pack, an Enterprise Edition option. Access is recorded in DBA_FEATURE_USAGE_STATISTICS, which matters in a licence audit. Without the pack use Statspack, which is free and installed from ?/rdbms/admin.

If you want DBAs and ERP admins to ask AWR history questions such as 'what got slower since the last RU' in plain English on your own servers, we can set that up.