SQL Diagnostic Report: Oracle 23ai Feature Now Available in 19.28
Introduction
Oracle Database 23ai introduced a powerful new diagnostic capability through the DBMS_SQLDIAG.REPORT_SQL
function, which generates comprehensive HTML diagnostic reports for SQL statements. The great news for Oracle 19c users is that this feature has been backported to Oracle Database 19.28, allowing you to leverage advanced SQL analysis without upgrading to 23ai.
Before this feature, DBAs typically relied on the awrsqrpt.sql
script to analyze SQL execution plans and performance metrics. The new REPORT_SQL
function provides a more comprehensive, graphical HTML report with deeper performance insights.
What Does SQL Diagnostic Report Provide?
The REPORT_SQL
function generates a comprehensive HTML diagnostic report that includes:
- Execution Plan History - Track how execution plans have evolved over time
- Cursor Sharing Information - Understand cursor behavior and sharing patterns
- Optimizer Statistics History - View changes in optimizer statistics
- Index Details - Analyze index usage and effectiveness
- Active Session History (ASH) Data - Examine ASH data related to the SQL statement
- Plan Statistics - Detailed statistics for each execution plan
- CPU Usage Metrics - Performance metrics including CPU consumption
Prerequisites
Before using this feature, ensure you have:
- Oracle Database 19.28 or later (or Oracle 23ai)
ADVISOR
role granted to your user- A directory object created for report output
Step-by-Step Implementation
Step 1: Create a Directory Object
First, create a directory object where the HTML reports will be stored:
SQL> CREATE OR REPLACE DIRECTORY DR_DIAGNOSTIC AS '/oracle/Diagnostic';
Directory created.
Step 2: Grant Permissions
Ensure your user has the necessary privileges:
SQL> GRANT READ, WRITE ON DIRECTORY DR_DIAGNOSTIC TO your_username;
Step 3: Identify the SQL_ID
Find the SQL_ID of the statement you want to analyze:
SQL> SELECT sql_id, sql_text, executions, elapsed_time
FROM v$sql
WHERE sql_text LIKE '%your_query_pattern%'
AND sql_text NOT LIKE '%v$sql%';
Step 4: Describe the REPORT_SQL Function
Let's examine the function signature:
SQL> DESC DBMS_SQLDIAG.REPORT_SQL
Parameter Type Mode Default?
------------ ----------- ----- --------
(RESULT) CLOB
SQL_ID VARCHAR2 IN
DIRECTORY VARCHAR2 IN Y
LEVEL VARCHAR2 IN Y
Step 5: Generate the SQL Diagnostic Report
Execute the following PL/SQL block to generate the report:
SQL> DECLARE
rpt1 CLOB;
BEGIN
rpt1 := DBMS_SQLDIAG.report_sql(
sql_id => 'a0na7qgw1zw98', -- Replace with your SQL_ID
directory => 'DR_DIAGNOSTIC',
level => 'ALL'
);
END;
/
PL/SQL procedure successfully completed.
Report Level Options
The LEVEL
parameter controls the amount of detail in the report:
Level | Description |
---|---|
BASIC | Minimal report with only essential details |
TYPICAL | Standard report with basic and advanced sections (default) |
ALL | Comprehensive report with maximum detail |
Example with Different Levels
Basic Level Report
DECLARE
rpt1 CLOB;
BEGIN
rpt1 := DBMS_SQLDIAG.report_sql(
sql_id => 'gtckcpxmp3ry7',
directory => 'DR_DIAGNOSTIC',
level => 'BASIC'
);
END;
/
Typical Level Report (Default)
DECLARE
rpt1 CLOB;
BEGIN
rpt1 := DBMS_SQLDIAG.report_sql(
sql_id => 'gtckcpxmp3ry7',
directory => 'DATA_PUMP_DIR',
level => 'TYPICAL'
);
END;
/
All Details Report
DECLARE
rpt1 CLOB;
BEGIN
rpt1 := DBMS_SQLDIAG.report_sql(
sql_id => 'gtckcpxmp3ry7',
directory => 'DATA_PUMP_DIR',
level => 'ALL'
);
END;
/
Locating and Viewing the Report
Step 1: Navigate to the Directory
[oracle@server ~]$ cd /oracle/Diagnostic
[oracle@server Diagnostic]$ ll
-rw-r--r--. 1 oracle asmadmin 22637 Aug 27 18:20 SQLR_a0na7qgw1zw98_202508271820.zip
Step 2: Extract the ZIP File
[oracle@server Diagnostic]$ unzip SQLR_a0na7qgw1zw98_202508271820.zip
Archive: SQLR_a0na7qgw1zw98_202508271820.zip
inflating: SQLR_a0na7qgw1zw98_202508271820.html
Step 3: View the HTML Report
[oracle@server Diagnostic]$ ll
-rw-r--r--. 1 oracle oinstall 125063 Aug 27 18:20 SQLR_a0na7qgw1zw98_202508271820.html
-rw-r--r--. 1 oracle asmadmin 22637 Aug 27 18:20 SQLR_a0na7qgw1zw98_202508271820.zip
Open the HTML file in a web browser to view the comprehensive diagnostic report.
Report File Naming Convention
The generated report follows this naming pattern:
SQLR_<SQL_ID>_<YYYYMMDDHH24MI>.html
Where:
SQL_ID
- The SQL identifier providedYYYYMMDDHH24MI
- Timestamp when the file was created
Generating Report Without Directory (Return as CLOB)
You can also return the report as a CLOB without writing to disk:
SET LONG 1000000
SET PAGESIZE 0
SET LINESIZE 32767
DECLARE
rpt1 CLOB;
BEGIN
rpt1 := DBMS_SQLDIAG.report_sql(
sql_id => 'a0na7qgw1zw98'
);
DBMS_OUTPUT.PUT_LINE(rpt1);
END;
/
Practical Use Cases
Use Case 1: Investigating Performance Degradation
When a SQL statement suddenly performs poorly:
-- Generate comprehensive report
DECLARE
rpt CLOB;
BEGIN
rpt := DBMS_SQLDIAG.report_sql(
sql_id => '<problematic_sql_id>',
directory => 'DR_DIAGNOSTIC',
level => 'ALL'
);
END;
/
The report will show execution plan changes, statistics changes, and historical performance metrics.
Use Case 2: Comparing Execution Plans Across Time
Generate reports for the same SQL_ID at different times to compare:
-- Today's report
DECLARE
rpt CLOB;
BEGIN
rpt := DBMS_SQLDIAG.report_sql(
sql_id => 'abc123xyz',
directory => 'DR_DIAGNOSTIC',
level => 'ALL'
);
END;
/
Use Case 3: Baseline Performance Analysis
Create reports for critical SQL statements as part of your baseline documentation:
-- Generate baseline reports for top 10 SQL by elapsed time
BEGIN
FOR rec IN (
SELECT sql_id
FROM (
SELECT sql_id, elapsed_time
FROM v$sql
WHERE parsing_schema_name NOT IN ('SYS','SYSTEM')
ORDER BY elapsed_time DESC
)
WHERE ROWNUM <= 10
)
LOOP
DECLARE
rpt CLOB;
BEGIN
rpt := DBMS_SQLDIAG.report_sql(
sql_id => rec.sql_id,
directory => 'DR_DIAGNOSTIC',
level => 'TYPICAL'
);
END;
END LOOP;
END;
/
Key Benefits
- Comprehensive Analysis - Single report contains multiple diagnostic dimensions
- Graphical HTML Format - Easy to read and share with team members
- Historical Tracking - View evolution of execution plans and statistics
- No Additional Tools - Built-in functionality, no external scripts needed
- Backported Feature - Available in 19.28 without upgrading to 23ai
Troubleshooting
Issue: ORA-20000: Directory does not exist
Solution: Verify the directory object exists and is accessible:
SELECT directory_name, directory_path
FROM dba_directories
WHERE directory_name = 'DR_DIAGNOSTIC';
Issue: Insufficient Privileges
Solution: Ensure you have the ADVISOR role:
GRANT ADVISOR TO username;
Issue: No Output File Generated
Solution: Check directory permissions on the OS level:
ls -ld /oracle/Diagnostic
chmod 755 /oracle/Diagnostic
Comparison with awrsqrpt.sql
Feature | awrsqrpt.sql | DBMS_SQLDIAG.REPORT_SQL |
---|---|---|
Output Format | Text | HTML (Graphical) |
Ease of Use | Interactive script | Single function call |
Customization | Limited | Level parameters |
Report Sections | Fixed | Comprehensive |
Integration | Manual | Programmatic |
Conclusion
The DBMS_SQLDIAG.REPORT_SQL
function represents a significant improvement in SQL diagnostics capabilities. With its backport to Oracle 19.28, DBAs can now leverage this powerful 23ai feature without waiting for a major database upgrade.
This feature streamlines SQL performance analysis by providing comprehensive, easy-to-read HTML reports that consolidate multiple diagnostic dimensions into a single view. Whether you're troubleshooting performance issues, documenting baselines, or analyzing execution plan changes, this tool should become a standard part of your diagnostic toolkit.
Comments
Post a Comment