Performance Monitoring

Oracle performance monitoring and tuning SQL queries

Session and Process Monitoring

Session monitoring and performance analysis (Access: DBA or performance views)

-- Active sessions
-- Access: DBA or users with DBA_SESSIONS privilege
SELECT 
    sid,
    serial#,
    username,
    program,
    machine,
    status,
    logon_time,
    last_call_et/60 AS "Idle (min)"
FROM v$session
WHERE status = 'ACTIVE'
ORDER BY last_call_et;

-- Top SQL by CPU usage
-- Access: DBA or users with DBA_HIST_SQLSTAT privilege
SELECT 
    sql_id,
    sql_text,
    executions,
    cpu_time/1000000 AS "CPU Time (sec)",
    elapsed_time/1000000 AS "Elapsed Time (sec)",
    buffer_gets,
    disk_reads
FROM v$sql
WHERE cpu_time > 0
ORDER BY cpu_time DESC
FETCH FIRST 10 ROWS ONLY;

-- Session wait events
-- Access: DBA or users with DBA_SESSION_WAITS privilege
SELECT 
    s.sid,
    s.username,
    w.event,
    w.wait_time,
    w.seconds_in_wait,
    w.state
FROM v$session s, v$session_wait w
WHERE s.sid = w.sid
AND s.status = 'ACTIVE'
ORDER BY w.seconds_in_wait DESC;

-- Long running queries
-- Access: DBA or users with DBA_SESSIONS privilege
SELECT 
    sid,
    serial#,
    username,
    sql_id,
    last_call_et/60 AS "Running (min)",
    sql_text
FROM v$session s, v$sql q
WHERE s.sql_id = q.sql_id
AND s.status = 'ACTIVE'
AND s.last_call_et > 300
ORDER BY s.last_call_et DESC;
Database Performance Metrics

Database performance metrics and statistics (Access: DBA or performance views)

-- Database performance statistics
-- Access: DBA or users with DBA_HIST_SYSMETRIC_SUMMARY privilege
SELECT 
    metric_name,
    value,
    unit
FROM v$sysmetric
WHERE metric_name IN (
    'Database CPU Time Ratio',
    'Database Wait Time Ratio',
    'SQL Service Response Time',
    'User Commits Per Sec',
    'User Rollbacks Per Sec'
)
ORDER BY metric_name;

-- Buffer cache hit ratio
-- Access: DBA or users with DBA_HIST_SYSMETRIC_SUMMARY privilege
SELECT 
    (1 - (physical_reads / (db_block_gets + consistent_gets))) * 100 AS "Buffer Cache Hit Ratio %"
FROM v$buffer_pool_statistics;

-- Library cache hit ratio
-- Access: DBA or users with DBA_HIST_LIBRARYCACHE privilege
SELECT 
    namespace,
    gets,
    gethits,
    ROUND(gethitratio * 100, 2) AS "Hit Ratio %"
FROM v$librarycache
ORDER BY namespace;

-- Top wait events
-- Access: DBA or users with DBA_HIST_SYSTEM_EVENT privilege
SELECT 
    event,
    total_waits,
    total_timeouts,
    time_waited/100 AS "Time Waited (sec)",
    average_wait/100 AS "Average Wait (sec)"
FROM v$system_event
WHERE wait_class != 'Idle'
ORDER BY time_waited DESC
FETCH FIRST 10 ROWS ONLY;

-- Database size and growth
-- Access: DBA or users with DBA_DATA_FILES privilege
SELECT 
    tablespace_name,
    SUM(bytes)/1024/1024/1024 AS "Size (GB)",
    COUNT(*) AS "Files"
FROM dba_data_files
GROUP BY tablespace_name
ORDER BY SUM(bytes) DESC;
SQL Performance Analysis

Comprehensive SQL performance analysis with detailed explanations and tuning recommendations (Access: DBA or performance views)

-- SQL PERFORMANCE ANALYSIS - COMPREHENSIVE GUIDE
-- ============================================
-- This guide shows how to analyze SQL performance, identify bottlenecks,
-- and optimize query execution

-- 1. TOP SQL BY EXECUTION TIME
-- ============================
-- Identifies the most time-consuming SQL statements
-- Access: DBA or users with DBA_HIST_SQLSTAT privilege
SELECT 
    sql_id,                   -- Unique SQL identifier
    sql_text,                 -- SQL statement text (truncated)
    executions,               -- Number of times executed
    elapsed_time/1000000 AS "Total Elapsed (sec)",  -- Total execution time
    cpu_time/1000000 AS "Total CPU (sec)",         -- Total CPU time
    (elapsed_time/1000000)/executions AS "Avg Elapsed (sec)",  -- Average execution time
    buffer_gets,              -- Number of buffer gets (logical reads)
    disk_reads,               -- Number of disk reads (physical reads)
    rows_processed,           -- Number of rows processed
    -- Calculate efficiency metrics
    ROUND((buffer_gets/executions), 2) AS "Avg Buffer Gets",
    ROUND((disk_reads/executions), 2) AS "Avg Disk Reads",
    ROUND((rows_processed/executions), 2) AS "Avg Rows Processed"
FROM v$sql
WHERE executions > 0
AND elapsed_time > 0
ORDER BY elapsed_time DESC
FETCH FIRST 10 ROWS ONLY;

-- 2. SQL EXECUTION PLANS - UNDERSTANDING THE PLAN
-- ==============================================
-- Execution plans show how Oracle executes a SQL statement
-- Access: DBA or users with DBA_HIST_SQL_PLAN privilege

-- Get execution plan for specific SQL ID
-- Replace '&sql_id' with actual SQL ID
SELECT 
    plan_table_output
FROM table(dbms_xplan.display_cursor('&sql_id', null, 'ALLSTATS LAST'));

-- Explanation of execution plan components:
-- - COST: Estimated cost of operation (lower is better)
-- - CARDINALITY: Estimated number of rows
-- - BYTES: Estimated bytes to be processed
-- - TIME: Estimated execution time
-- - Operation types:
--   * TABLE ACCESS FULL: Full table scan (usually expensive)
--   * INDEX RANGE SCAN: Index scan (usually efficient)
--   * NESTED LOOPS: Join method (good for small result sets)
--   * HASH JOIN: Join method (good for large result sets)
--   * SORT: Sorting operation (may be expensive)

-- 3. SQL STATISTICS ANALYSIS
-- ==========================
-- Detailed statistics for specific SQL statement
-- Access: DBA or users with DBA_HIST_SQLSTAT privilege
SELECT 
    sql_id,                   -- SQL identifier
    plan_hash_value,          -- Execution plan hash
    executions,               -- Number of executions
    elapsed_time/1000000 AS "Elapsed Time (sec)",    -- Total elapsed time
    cpu_time/1000000 AS "CPU Time (sec)",            -- Total CPU time
    buffer_gets,              -- Total buffer gets
    disk_reads,               -- Total disk reads
    rows_processed,           -- Total rows processed
    -- Calculate ratios and efficiency
    ROUND(buffer_gets/executions, 2) AS "Avg Buffer Gets Per Execution",
    ROUND(disk_reads/executions, 2) AS "Avg Disk Reads Per Execution",
    ROUND(rows_processed/executions, 2) AS "Avg Rows Per Execution",
    -- Calculate hit ratios
    ROUND((1 - (disk_reads/NULLIF(buffer_gets, 0))) * 100, 2) AS "Buffer Hit Ratio %"
FROM v$sql
WHERE sql_id = '&sql_id'  -- Replace with actual SQL ID
AND executions > 0;

-- 4. SQL TEXT RETRIEVAL
-- ====================
-- Get full SQL text for analysis
-- Access: DBA or users with DBA_HIST_SQLTEXT privilege
SELECT 
    sql_id,                   -- SQL identifier
    sql_text                  -- Complete SQL statement
FROM v$sql
WHERE sql_id = '&sql_id';    -- Replace with actual SQL ID

-- 5. SQL EXECUTION HISTORY
-- =======================
-- Historical performance data for SQL statement
-- Access: DBA or users with DBA_HIST_SQLSTAT privilege
SELECT 
    sql_id,                   -- SQL identifier
    snap_id,                  -- AWR snapshot ID
    executions_delta,         -- Executions in this snapshot
    elapsed_time_delta/1000000 AS "Elapsed Time (sec)",  -- Elapsed time in snapshot
    cpu_time_delta/1000000 AS "CPU Time (sec)",          -- CPU time in snapshot
    buffer_gets_delta,        -- Buffer gets in snapshot
    disk_reads_delta,          -- Disk reads in snapshot
    -- Calculate averages for this snapshot
    ROUND(elapsed_time_delta/1000000/NULLIF(executions_delta, 0), 4) AS "Avg Elapsed (sec)",
    ROUND(cpu_time_delta/1000000/NULLIF(executions_delta, 0), 4) AS "Avg CPU (sec)"
FROM dba_hist_sqlstat
WHERE sql_id = '&sql_id'     -- Replace with actual SQL ID
ORDER BY snap_id DESC;

-- 6. PERFORMANCE TUNING RECOMMENDATIONS
-- ====================================
-- Based on the analysis above, here are common tuning strategies:

-- For high buffer gets:
-- - Add appropriate indexes
-- - Optimize WHERE clauses
-- - Use proper join methods

-- For high disk reads:
-- - Increase buffer cache size
-- - Optimize queries to use indexes
-- - Consider partitioning large tables

-- For high elapsed time:
-- - Analyze execution plan
-- - Consider query rewrite
-- - Optimize table statistics

-- For high CPU time:
-- - Simplify complex calculations
-- - Use appropriate data types
-- - Consider function-based indexes

-- 7. INDEX USAGE ANALYSIS
-- ======================
-- Check if indexes are being used effectively
SELECT 
    i.index_name,             -- Index name
    i.table_name,             -- Table name
    i.column_name,            -- Column name
    s.used,                   -- Whether index is used
    s.startup_time,           -- When statistics were collected
    s.usage_count            -- How many times index was used
FROM dba_indexes i, v$object_usage s
WHERE i.index_name = s.index_name
AND i.owner = s.owner
ORDER BY s.usage_count DESC;

-- 8. QUERY OPTIMIZATION CHECKLIST
-- ===============================
-- 1. Ensure statistics are up to date
-- 2. Use appropriate indexes
-- 3. Write efficient WHERE clauses
-- 4. Use proper join methods
-- 5. Avoid unnecessary functions in WHERE clauses
-- 6. Use appropriate data types
-- 7. Consider partitioning for large tables
-- 8. Monitor and analyze execution plans regularly