Perf Tuning by Amanpandey
Perf Tuning by Amanpandey
Aman Pandey
Step-by-Step Descriptions:
1. Login to Database
• Begin by logging into the Oracle Database system and establishing the connection to start
diagnosing the performance issue.
• Objective: Check for any resource utilization spikes at the OS level. This could be related to
CPU, memory, or disk I/O.
❖ Steps:
o Engage the Linux Sysadmin (LSA) or SysAdmin Team if there are high spikes in CPU,
memory, or disk I/O.
o If other services are consuming heavy resources, restart the services after getting
approval from the respective teams.
o Engage the Network Team to check the strength of incoming connections, as high
network utilization can also cause performance degradation.
o Engage Service/Application-specific teams to check on specific services like security or
endpoint services that may be impacting the server.
• Objective: Once OS-level checks are completed or ruled out, start focusing on database-
related processes.
❖ Components to Review:
o AWR Report: Automatic Workload Repository reports help identify SQL statements, wait
events, and resource consumption.
o ASH Report: Active Session History provides session-level data for real-time analysis.
o Listener Log: Identify issues related to network connection and listener services.
o Blocking Sessions: Investigate if any sessions are blocking others, potentially causing
performance bottlenecks.
❖ Action:
o Identify the blocking sessions and work with the application team to confirm if they can
be killed.
o Kill the blocking sessions after confirmation from the application team to clear
bottlenecks.
• Objective: Analyze the top wait events or resource-intensive SQLs from the AWR and ASH
reports to identify the root cause of the performance degradation.
❖ Sub-Steps:
✓ Ask the application team about:
o Any recent changes to code.
o Specific SQL queries that are affected.
o The last best-known date and time when performance was normal.
✓ Use the following tools to analyze SQL performance:
o SQLTXPLAIN (SQLT): For SQL diagnostics.
o SQLHC (SQL Health Check): For analyzing SQL health.
o ADDM (Automatic Database Diagnostic Monitor): For system-wide performance
diagnosis.
o SQL Tuning Advisor: Provides SQL optimization recommendations.
o HangAnalyze/TFA: For identifying system-wide performance issues.
• With the help of AWR, ASH, ADDM, SQLT, and SQL Tuning Advisor, identify the major
resource-consuming areas, including:
o Memory: Tuning related to SGA/PGA.
o Plan Flip: If execution plans change frequently, causing instability.
o I/O: Slow disk reads/writes or full table scans due to missing indexes.
6. Memory Tuning
• Objective: Pin the optimal execution plan to prevent frequent plan changes.
• Actions:
o If you notice frequent plan flips, pin the optimal Plan Hash Value to stabilize query
performance.
8. I/O Tuning
• Objective: Ensure that statistics are up to date, as stale stats can lead to poor execution
plans.
• Actions:
o Gather fresh statistics on any table or index object that is impacting the SQL
performance.
➢ If the issue is still unresolved, raise a support case with Oracle Support and share all relevant
logs and reports. The issue could be due to a bug or might require a patch for better
optimization.
Conclusion:
This flowchart-based approach provides a structured method to diagnose and resolve Oracle
Database performance issues. Each step allows the DBA to identify possible root causes, whether at
the OS level, database configuration, or SQL/query optimization. By following this methodology,
issues can be resolved systematically with minimal impact on business operations.
Commands and Queries
Login to DB:
OS Checks:
✓ ps -eo pmem,pcpu,vsize,pid,cmd | sort -k 1 -nr | head -50
✓ LOAD: sar -q -f /var/log/sa/sa03
✓ CPU: sar -p -f /var/log/sa/sa03
✓ IO Wait: sar -u -f /var/log/sa/sa03
✓ Paging: sar -B -f /var/log/sa/sa03
✓ Swap Memory: sar -S -f /var/log/sa/sa03
✓ Memory – Swap Utilization: free -h
✓ Vmstat
✓ Top
DB Checks:
✓ AWR Report:
✓ ASH Report:
✓ Blocking Session:
SET LINES 750 PAGES 9999
COL blocking_status FOR A100
SELECT s1.sid || ',' || s1.serial# || ' (' || s1.username || '@' ||
s1.machine || ')'
|| ' is blocking ' || s2.sid || ',' || s2.serial# || ' (' ||
s2.username || '@' || s2.machine || ')' AS blocking_status
FROM v$lock l1, v$session s1, v$lock l2, v$session s2
WHERE s1.sid = l1.sid
AND s2.sid = l2.sid
AND l1.BLOCK = 1
AND l2.request > 0
AND l1.id1 = l2.id1
AND l1.id2 = l2.id2
ORDER BY s1.sid;
✓ DB Alert Log:
✓ Listener Log:
✓ Long Running Queries:
SET LINESIZE 750 PAGES 9999
COLUMN box FORMAT A30
COLUMN spid FORMAT A10
COLUMN username FORMAT A30
COLUMN program FORMAT A30
COLUMN os_user FORMAT A20
COL LOGON_TIME FOR A20
SELECT b.inst_id,
b.sid,
b.serial#,
a.spid,
SUBSTR(b.machine, 1, 30) box,
TO_CHAR(b.logon_time, 'dd-mon-yyyy hh24:mi:ss') logon_time,
SUBSTR(b.username, 1, 30) username,
SUBSTR(b.osuser, 1, 20) os_user,
SUBSTR(b.program, 1, 30) program,
b.status,
b.last_call_et AS last_call_et_secs,
b.sql_id
FROM gv$session b,
gv$process a
WHERE b.paddr = a.addr
AND a.inst_id = b.inst_id
AND type = 'USER'
AND b.status = 'ACTIVE'
ORDER BY logon_time;
✓ Stale Table/Index under a bad SQL_ID:
set pagesize 100
set linesize 150
set trims off
set tab off
set verify off
column table_name format a50
column index_name format a50
column object_type format a40
column owner format a40
accept sql_id prompt 'Enter the SQL ID: '
PROMPT ==========
PROMPT Tables
PROMPT ==========
with plan_tables as (
select distinct object_name,object_owner, object_type
from v$sql_plan
where object_type like 'TABLE%' and sql_id = '&sql_id')
select t.object_owner owner,
t.object_name table_name,
t.object_type object_type,
decode(stale_stats,'NO','OK',NULL, 'NO STATS!', 'STALE!')
staleness
from dba_tab_statistics s, plan_tables t
where s.table_name = t.object_name
and s.owner = t.object_owner
and s.partition_name is null
and s.subpartition_name is null
order by t.object_owner, t.object_name;
PROMPT ==========
PROMPT Indexes
PROMPT ==========
with plan_indexes as (
select distinct object_name,object_owner, object_type
from v$sql_plan
where object_type like 'INDEX%' and sql_id = '&sql_id')
select i.object_owner owner,
i.object_name index_name,
i.object_type object_type,
decode(stale_stats,'NO','OK',NULL, 'NO STATS!', 'STALE!') staleness
from dba_ind_statistics s, plan_indexes i
where s.index_name = i.object_name
and s.owner = i.object_owner
and s.partition_name is null
and s.subpartition_name is null
order by i.object_owner, i.object_name;
References:
For further reading and to dive deeper into the performance tuning of queries, the following
Oracle MOS (My Oracle Support) documents provide extensive guidance and techniques for
optimizing SQL performance: