You are on page 1of 26

ORACLE 9i-10g PERFORMANCE TUNING

(rev2.1) – June, 2007 – by Ergem PEKER

Version: Oracle Database 9.2.0.4


Formatter: Toad 9.0.1.8
(rev1.1) – January, 2009 – by Ergem PEKER
10g enhancements and some more functionalities.

Foreword

You will find:


- Short explanations about system views and files to examine for
performance tuning.
- Lists of views and parameters.
- Lots of statements for obtaining system information and
statistics.

You will not find:


- Performance tuning road maps. (I assume you have informed)
- Subject explanations. (There are lots of whitepapers in google)
- Detailed information about views, parameters. (You can be informed
any of the views by selecting any of it)

Which files should be examined

- Alert log file

Server log file for instance level alerts.

--
-- finding the location of the alert_<SID>.log file
--
select * from v$parameter where name = 'background_dump_dest';
-- sample output: /data1/oracle1/orahome1/admin/oradb1/bdump

Search for ORA 600 internal errors


ORA 7445
ORA 1578 block corruption errors

Alert log file contains;


Checkpoint start & end times
Incomplete checkpoint
Time and performing archiving
Instance recovery and end time
Deadlock and timeout errors

- Trace files

Session log files for session(user) level alerts.

Server tracing can be enabled or disabled at the session or instance level.


Contains statistics for traced SQL statements.

Instance level tracing


--
-- how to examine and change the sql_trace parameter
--
select value from v$parameter where name='sql_trace';

1
-- sample output: FALSE
alter system set sql_trace=TRUE scope=spfile;
-- instance needed to be restarted for changes
select value from v$parameter where name='sql_trace';
-- sample output: TRUE

Session level tracing


--
-- enable sql tracing for a session
--
-- dbms_system.set_sql_trace_in_session(<SID>,<SERIAL#>,[TRUE|FALSE])
EXEC dbms_system.set_sql_trace_in_session(10, 1008, TRUE);
EXEC dbms_system.set_ev(10, 1008, 10046, 12, NULL);
/*** meaning of levels of a trace
LEVEL Waits Binds
1 FALSE FALSE
4 FALSE TRUE
8 TRUE FALSE
12 TRUE TRUE
*/
--
-- enable sql tracing for your own session
--
alter session set sql_trace=TRUE;

--
-- finding a sessions tracefile name
--
-- first you need to have necessary privileges on DBMS_SUPPORT system
package
grant execute on DBMS_SUPPORT to public;
create public synonym DBMS_SUPPORT for SYS.DBMS_SUPPORT;
-- now you can the following statement
select
db_name.value ||
'_ora_' ||
v$process.spid ||
nvl2(v$process.traceid, '_' || v$process.traceid, NULL ) ||
'.trc'
from
v$parameter u_dump
cross join v$parameter db_name
cross join v$process
join v$session
on v$process.addr = v$session.paddr
where
u_dump.name = 'user_dump_dest' and
db_name.name = 'db_name' and
v$session.sid=dbms_support.MYSID;
--
-- another way of finding sid of my own session
--
select distinct(SID) from v$mystat;

--
-- identifying tracefile identifier (name) for your session
--
alter session set tracefile_identifier='my_trace_file';
alter session set sql_trace=TRUE;

--
-- finding the path and the name of a sessions trace file
--
select c.value || '/ora_' || b.spid || '.trc'
from v$session a, v$process b, v$parameter c
where name='user_dump_dest'
and a.paddr=b.addr

2
-- and a.sid=<SID>;

--
-- obtain SID and SERIAL# for a specific session
--
select SID, SERIAL#, USERNAME, MACHINE
from v$session
where username='D_EPEKER';

NOTES:
1- Run oraclehome/rdbms/admin/catproc.sql script for dbms_system packages
2- If you want to obtain wait times in session trace file you should enable
timed_statistics
3- statistics_level init parameter should be at least TYPICAL to gather
reliable statistics, wait events, advisories.

--
-- modifying statistics_level
--
select value from v$parameter where name='statistics_level';
alter system set statistics_level='TYPICAL';
-- allowed values are [ALL|TYPICAL|BASIC]

--
-- enabling timed_statistics
--
select value from v$parameter where name='timed_statistics';
-- sample output: FALSE
alter system set timed_statistics=TRUE;
select value from v$parameter where name='timed_statistics';
-- sample output: TRUE

Which views should be interested

General system views and tools can be summerized as follows

V$xxx views
Dba_xxx views
Statspack
Utlbstat.sql
Utlestat.sql
Oracle Wait Interface(OWI)
Oracle diagnostics tuning packs

System related views


V$system_event
Cumulative information of waits and wait events. Ever instance
restart resets the information.
V$sysstat
V$event_name
V$fixed_table

Instance/database
V$database //database info
V$instance //instance info
V$option
V$parameter //system init parameters
V$px_process_sysstat //parallel query system statistics
V$process //information about currently active processes

3
V$waitstat //contention statistics
V$system_event //total waits for particular events

Disk
V$datafile //datafile detailed info
V$filestat //data file read/write statistics
V$dbfile //datafile short list
V$tempfile //temporary file detailed info
V$tempstat //read/write for datafiles in temporary
tablespace

Memory
V$buffer_pool_statistics //buffer pool allocation on the instance
oracle_home/rdms/admin/catperf.sql
V$db_object_cache //database object cached in library cache
V$librarycache //library cache performance and activity
statistics
V$rowcache //data dictionary hits and misses activity
V$sysstat //basic instance statistics
V$sga //sga brief info
V$sgastat //statistics about sga usage
V$pgastat //statistcis about pga usage
V$sql
V$sqltext
V$sqlarea //sql commands currently exists in sqlarea
V$sqlstat //statistics of sql statements
V$open_cursor
V$librarycache

v$shared_pool_advice
v$db_cache_advice
v$pga_target_advice

Contention
V$lock
V$rollname
V$rollstat //statistics for all online rollback segments
V$waitstat //block contention statistics
The timed_statistics init.ora parameter
should be set to true
V$latch //statistics for each type of latch
V$enqueue

User/Session
V$lock //locks currently held by the server and
outstanding requests for a lock or latch
V$open_cursor //cursors curently opened by each session
V$process
V$sort_usage //size of temporary segments and sessions
creating them, identification of disk sorts
V$session
V$session_longops
V$sesstat //user session statistics
V$statname
V$transaction
V$session_event //information on waits for which active
sessions are waiting
V$event_name
V$session_wait //resources or event for which active sessions
are waiting
V$px_sesstat //information about the sessions running in
parallel

4
V$px_session
V$session_object_cache

NOTES:
Examples, usages and detailed explainations for these views will ve covered
lately in this document.

Tuning SGA

--
-- monitoring SGA system parameters
--
-- max size of the sga
select name, value, description from v$parameter where name='sga_max_size';
-- sum of all values of the following query cannot exceed sga_max_size
select sum(value) from
(
select name, value, description from v$parameter
where name in ('java_pool_size',
'shared_pool_size',
'large_pool_size')
UNION
select name, value, description from v$parameter where name like
'db_%cache_size'
UNION
select name, value, description from v$parameter where name='log_buffer'
);
--
-- lets have a look at something
-- the value of sga_max_size may not be equal to the sum of its components
-- the difference between these two values will give you the approximate
-- free space
--
select trunc(((t2.sga_max_size - t1.total_sga_params)/1024/1024)) FREE_MB
from
(
select sum(value) total_sga_params from
(
select name, value, description from v$parameter
where name in ('java_pool_size',
'shared_pool_size',
'large_pool_size')
UNION
select name, value, description from v$parameter where name like
'db_%cache_size'
UNION
select name, value, description from v$parameter where
name='log_buffer'
)
) t1
,
(
select sum(value) sga_max_size from v$parameter where
name='sga_max_size'
) t2;

--
-- other ways of obtaining free sga size
--
select * from v$sgastat where name='free memory';
select current_size/1024/1024 MB from v$sga_dynamic_free_memory;

--
-- changing sga and sga componenets values
--

5
-- recommended: sga_max_size should be phsical_memory/2
alter system set sga_max_size=500M scope=spfile;
-- changes of this parameter will take affect after instance restart
alter system set java_pool_size=150M scope=spfile;
-- changes of this parameter will take affect after instance restart
alter system set shared_pool_size=150M;
alter system set large_pool_size=50M;
alter system set db_cache_size=150M;
--
-- which system parameter can be changed without an instance restart
--
select * from v$parameter where issys_modifiable='IMMEDIATE'
--
-- following parameter needs an instance restart
--
select * from v$parameter where issys_modifiable!='FALSE'
-- to change these kind of system parameters following steps can be
followed
alter system set <name>=<value> scope=spfile;
-- from now on you should login from sqlplus "/as sysdba"
alter system checkpoint;
shutdown immediate;
startup;

Advices for SGA

--
-- advices for sga
--
select * from V$SHARED_POOL_ADVICE;
select * from V$DB_CACHE_ADVICE;
select * from V$PGA_TARGET_ADVICE;

NOTES:
1- db_cache_advice system parameter should be ON for v$shared_pool_advice
system view can be up-to-date.
2- for all advice views statistics_level system parameter should be at
least in BASIC mode.

--
-- setting db_cache_advice system parameter
--
select
name,
value,
issys_modifiable,
description
from
v$parameter
where
name='db_cache_advice';
alter system set db_cache_advice='ON';
select
name,
value,
issys_modifiable,
description
from
v$parameter
where
name='db_cache_advice';

6
Tuning Shared Pool

Shared pool includes cursors, sql statements, plsql blocks which are
parsed/executed and stored/cached in memory. It is important to optimize
the plsql blocks and/or sql commands so sessions can use the same commands
without parsing but only executing the statements. This improves the
application response times. Hints to optimize your sql code will be given
in the following sections.

Other blocks included by Shared Pool are; SQL, PLSQL, Library Cache
(metadata for tables, indexes and views) and Row Cache (Dictionary cache,
points to buffer cache – db_cache_size).

There are also some system paramters that you can decide to set (or not to
set) to improve your instance performance. These parameters are covered
below.

--
-- system wide statistics for parsing and execution of statements
--
-- the statement sent for parsing and found in cursor cache, this means the
statement is not really parsed
select * from v$sysstat where name like 'session cursor cache hits';
-- the count for sql parses
select * from v$sysstat where name like 'parse count (total)';
-- the count for sql executions
select * from v$sysstat where name like 'execute count';
--
-- the real parse count for executions
-- desired result should be as close as to zero
--
select total_parse/execute_count from
(
select (t2.value - t1.value) total_parse from v$sysstat t1, v$sysstat t2
where t1.name='session cursor cache hits'
and t2.name='parse count (total)'
) t1,
(
select value execute_count from v$sysstat where name='execute count'
) t2;
NOTE:
If the result of the above query is far from zero this means oracle
instance loses some time for parsing the statement instead of executing
them. First action should be reviewing sql statements of the application.
Bind variables should be a proper approach. We will look at database wide
tuning actions.

--
-- top consumers in shared_pool
--
select
name,
ceil(bytes/1024/1024) || 'MB' MB
from
v$sgastat
where
pool='shared pool'
order by
bytes desc;

--

7
-- session wide (user level) statistics for parsing and executin of
statements
--
-- session wide statistics are same as system wide. but there is only
-- a SID column to fetch only the desired session statistics
select
t1.value,
t2.name,
t3.sid,
t3.username,
t3.machine
from
v$sesstat t1,
v$statname t2,
v$session t3
where
t1.statistic# = t2.STATISTIC# and
t1.sid = t3.sid and
t2.name in ('session cursor cache hits','parse count (total)','execute
count') and
username is not null
order by t3.sid, t1.value desc;

--
-- look for any cursors cached for a session, and compare with system
parameter
--
select
t1.value curr_cached,
t4.value max_cached,
t3.username,
t3.sid,
t3.serial#
from
v$sesstat t1,
v$statname t2,
v$session t3,
v$parameter2 t4
where
t1.statistic# = t2.statistic# and
t1.sid=t3.sid
and t4.name='session_cached_cursors'
and t2.name = 'session cursor cache count';
--
-- obtaining cache hit ratios of the sqlarea and some other memory
allocations
--
select * from v$librarycache;
/*
Desired value for gethitratio is over %90
gets: number of lookups (parse)
pins: number of reads (execution)
reloads: the number of library cache misses
invalidations: if an object is modified
*/
--
-- comparison for executions and misses from library cache
--
-- desired value of course should be as small as possible like < %1
select
sum(pins) "executions" ,
sum(reloads) "cache misses" ,
sum(reloads) / sum(pins)
from
v$librarycache;
--

8
-- detailed examination of library cache
--
-- librarycache reloads should be max 10%
-- pins-pinhits: total loads from the physical disk
-- too many invalidations should be considered
select
namespace,
pins,
pins-pinhits loads,
reloads,
invalidations,
100 * (reloads-invalidations)/(pins-pinhits) "%RELOADS"
from
v$librarycache
where
pins>0
order by
namespace;

--
-- examine the sqlarea
--
select
t1.sql_text,
t1.users_executing,
t1.executions,
t1.disk_reads,
t1.buffer_gets,
t1.first_load_time,
t2.username
from
v$sqlarea t1,
dba_users t2
where
t1.parsing_user_id = t2.user_id
order by disk_reads desc;
--
-- you can examine execution plans of the queries that are currently in
memory
-- and who are running then
--
select
t1.hash_value,
t1.operation,
t1.options,
t1.optimizer,
t1.object_owner || '.' || t1.object_name,
t2.sql_text,
t2.users_executing,
t3.username
from
v$sql_plan t1,
v$sqlarea t2,
v$session t3
where
t1.hash_value = t2.hash_value and
t2.address = t3.sql_address;
--
-- individual objects in shared_pool
--
-- KEPT=YES clause will give you the pinned objects
select * from v$db_object_cache order by sharable_mem desc;

--
-- 10G R2 enhancement. Statistic for SQL statements.
-- uses less system resources
--

9
select * from v$sqlstats;
--
--
--
select * from v$rowcache
/*
Gets : numberof requests on objects
Getmisses : number of requests in resulting misses
*/
--
-- library cache misses results dictionary missed
-- dictionary cache misses are relatively cheaper
-- every rowcache miss costs one row od dictionary data retrieved
--
select
parameter,
sum(gets) gets,
sum(getmisses) getmisses,
sum("COUNT") num,
sum(usage)
from
v$rowcache
where
getmisses>0
group by
parameter
order by
parameter;

NOTES
1- You can find out the queries currently in sqlarea. But tuning the sql
statements will be covered later in this document. Nowly we are
concantrated on tuning shared_pool tuning.
2- If you cant find any cached cursors, you should check for
session_cached_cursors system parameter. Forexample in my test database the
following query was returning ‘0’ which means no cursor (statement) is
cached in memory. As a result all the queries of a session were reparsed by
oracle.
--
-- session_cached_cursors system parameter
--
select value from v$parameter where name='session_cached_cursors';
alter system set session_cached_cursors=50 scope=spfile;
-- changes will take effect after instance restart

3- Another parameter is cursor_sharing which effects the sql performance in


an instance.

--
-- cursor_sharing init parameter
--
select name, value from v$parameter where name='cursor_sharing';
alter system set cursor_sharing='SIMILAR';
-- alter system set cursor_sharing=''[EXACT|SIMILAR|FORCE]';

4- If you dont have a plenty of memory then you can set the following
parameter for faster execution of some cursors

--
-- cursor_space_for_time
--
-- the cursor will remain open until the application closes it
select * from v$parameter where lower(name)='cursor_space_for_time';
alter system set cursor_space_for_time=TRUE scope=spfile;

10
-- changes will take effect after instance restart
-- available values: [TRUE|FALSE]

5- Dont forget, sometimes you should decrease the value of the


shared_pool_size, check the following;

if
Request_miss = 0 or not increasing
Free_memory >= %50 of the shared_pool_reserved_size
Then
Decrease the size of the shared_pool
End if

6- 10G R2 enhancement: _use_kks_mutex init.ora parameter can bu used. This


new algorithm is faster and less cpu consumer.

_use_kks_mutex=TRUE

7- Check the sqlarea for problems of pinning sql objects. If you find sqls
with same PLAN_HASH_VALUE but different SQL_ID ‘s. Or another method for
selecting not cached sql statemets is selecting and counting first n
characters (substr(sqltext,1,20)) of sqltext column of v$sqlarea.

8- You can manually pin the objects in shared_pool by using


dbms_shared_pool package.

list of views for shared_pool management


v$sysstat
v$sesstat
v$statname
v$session
v$sga
v$sgastat
v$librarycache
v$sql //contains one row for each child of the original
sql text same as v$sqlarea but group by clause
v$sqlarea //full statistics about shared cursors
v$sqltext //full sql text without truncation
dba_users
v$db_object_cache
v$rowcache

parameters
session_cached_cursors
cursor_sharing
shared_pool_size
shared_pool_reserved_size
cursor_space_for_time
open_cursors

Tuning Large_pool

Used for I/O Processes


Backup and restore operations; export, import and RMAN backups.
If set in shared server then this will be used for users instead of PGA.

--
-- changing large_pool_size parameter
--
select * from v$parameter where name like '%large_pool_size%';
alter system set large_pool_size=50M;

11
Tuning PGA

For assigning a global memory area to users “program area”. Users sort
operations, hash operations and workareas will be provided from this
Program Global Area.

--
-- pga_aggregate_target
--
select value/1024/1024 MB from v$parameter where name =
'pga_aggregate_target';
alter system set pga_aggregate_target=500M;

NOTE:
If you want pga_aggregate_target to take affect, workarea_size_policy
should be set to AUTO. MANUAL means you are using *_area_size parameters
and these parameter values are assigned as memory segments per user.

--
-- work_area_size_policy
--
select value from v$parameter where name='workarea_size_policy';
alter system set workarea_size_policy=AUTO;
-- allowed values: AUTO|MANUAL

--
-- *.area_size parameters
--
select name, value from v$parameter where name like '%_area_size';
-- unused parameters if you are using workarea_size_policy=AUTO

--
-- monitoring sga internals
--
select name, trunc(value/1024/1024) MB from v$pgastat;
--
-- oracle advice for PGA
--
select * from V$PGA_TARGET_ADVICE;
-- for details refer to "Tuning SGA"
--
-- determining sessions that consume more than 30000 bytes of PGA memory
--
select t2.username , t1.name , t3.value
from v$statname t1, v$session t2, v$sesstat t3
where
t2.sid = t3.sid and
t1.statistic# = t3.statistic# and
t2.type = 'user' and
t2.username is not null and
t1.name='session pga memory' and
t3.value >= 30000;

list of views for shared_pool management


v$pgastat
v$sesstat
v$session
v$statname
v$pga_target_advice

parameters
workarea_size_policy

12
pga_aggregate_target
*_area_size

Tuning logical IO

There are two main types of IO, logical IO and physical IO. We prefer
logical IO because instance reads data from memory called logical IO which
is much more faster than physical IO which reads data from hard disk. To
lower the physical IO, we use db_buffer_cache parameter which assigns some
part of the memory for caching hard disk data.

This section includes both logical IO and physical IO performance tuning


topics.

--
-- db_cache_size
--
select name, value from v$parameter where name = 'db_cache_size';
alter system set db_cache_size=350M;
alter system set db_keep_cache_size=10M;
alter system set db_recycle_cache_size=10M;

NOTE
Tables which are more frequently used by sessions and has relatively small
amount of update with long time intervals should be in keep_cache_size
which is stored in memory and are not in LRU chain of default_cache_size.
Recycle_cache_size is for tables which you dont want to be in memory for a
long time. Default_cache_size is always there for any undefined
buffer_pools.

--
-- static view of buffer pool, can inspect keep_cache_size and
recycle_cache_size
--
select * from v$buffer_pool;

--
-- buffer pool statistics for detailed information
--
select * from v$buffer_pool_statistics;
/*
NAME: Name of the buffer pool
PHYSICAL_READS: Number of physical reads
DB_BLOCK_GETS: Number of reads for INSERT, UPDATE and DELETE
CONSISTENT_GETS: Number of reads for SELECT
DB_BLOCK_GETS + CONSISTENT_GETS = Total Number of reads
*/

--
-- as with the above information the following ratio should be very close
to zero
-- if not then we are reading data physical
--
select
name,
trunc(physical_reads/(decode(db_block_gets,0,1,1)+consistent_gets),3)
value
from
v$buffer_pool_statistics;
/*
keep: %10 of default
recycle: %2 of default
*/

13
--
-- which objects are in memory cache
--
select
count(1) count,
t1.objd,
t2.name,
t3.OBJECT_NAME,
t3.OWNER
from
v$bh t1,
v$datafile t2,
dba_objects t3
where
t1.file# = t2.file# and
t1.objd = t3.OBJECT_ID and
t3.owner not in ('SYS', 'SYSTEM')
group by t3.object_name, t3.owner, t2.name, t1.objd
order by count desc, t3.object_name;

--
-- altering a table buffor_pool
--
alter table <tablename> storage (buffer_pool keep);
alter table <tablename> storage (buffer_pool recycle);
alter table <tablename> storage (buffer_pool default);

--
-- have a look at systems cache hit ratio
--
-- as you can expect the result should be as close as 1
select
1 - (phy.value - lob.value - dir.value) / ses.value cache_hit_ratio
from
v$sysstat ses,
v$sysstat lob,
v$sysstat dir,
v$sysstat phy
where
ses.name = 'session logical reads' and
dir.name = 'physical reads direct' and
lob.name = 'physical reads direct (lob)' and
phy.name = 'physical reads';

--
-- comparison of logical and physical reads in user level
--
select
t2.username,
t1.block_gets,
t1.consistent_gets,
t1.physical_reads
from
v$sess_io t1,
v$session t2
where
t1.sid=t2.sid and
t2.username is not null
order by username;
--
-- two important system wait events
--
select name,value from v$sysstat where name = 'free buffer inspected'
select
event,
total_waits
from
v$system_event

14
where
event in ('free buffer waits', 'buffer busy waits');

--
-- if the session is currently waiting on "buffer busy waits"
-- p1 ,p2 ,p3 columns has meanings
--
select
p1 as "file",
p2 as "block",
p3 as "reason"
from
v$session_wait
where
event = 'buffer busy waits';

--
-- checks if there is any session currently waiting for buffer busy waits
(freelist contention)
--
select
s.segment_name,
s.segment_type,
s.freelists,
w.wait_time,
w.seconds_in_wait,
w.state
from
dba_segments s,
v$session_wait w
where
w.event='buffer busy waits'
and w.p1 = s.header_file
and w.p2 = s.header_block;

--
-- another way of examining block waits
--
select
distinct owner,
segment_name,
segment_type
from
dba_extents t1,
v$session_wait t2
where
file_id = t2.p1 and
t2.p2 between block_id and block_id + blocks - 1 and
t2.event = 'buffer busy waits';

list of views for db_cache_size management


v$db_cache_advice

v$system_event
v$session_event
v$session_wait
v$session

v$sesstat
v$sysstat
v$bh
v$sess_io

v$buffer_pool_statistics
v$buffer_pool

dba_segments

15
parameters
db_cache_advice //[ON|OFF|READY]
db_block_checsum //[TRUE|FALSE]
db_cache_size
db_keep_cache_size
db_recycle_cache_size
db_2K_cache_size
db_4K_cache_size
db_8K_cache_size
db_16K_cache_size
db_32K_cache_size

Tuning Physical IO

You can barely tune you system for best performance logical IO but it
doesnt mean your system will not make any physical IO from your Disk
Subsystem because you data is on the disk systems and of course you cannot
buy enough memory to store all your data in memory. Now we will going to
interested in pyhsical IO performance.

1- When creating a tablespace always be careful about defining “extent


management” and “segment space management” parameters. “extent management
local” parameter can have two distinct values. Local: stands for extent
management should be in datafile headers which is using bitmap lookup table
and far faster than Dictionary: extent management is done in system
tablespaces which has lower performance.

--
-- creating a tablescpace
--
create tablespace <ts_name>
datafile '$home/oradata/<SID>/<dbf_name>.dbf'
size=10M
extent management local
segment space management AUTO;
create table <table_name> (<col_name> number) tablespace <ts_name>;

2- Be careful about your RAID levels

RAID Type of Raid Control_File Database_File Redo_Log Archive_Log


---- ------------ ------------ ------------- -------- -----------
0 Striping Avoid OK Avoid Avoid
1 Shadowing Best OK Best Best
1+0 Striping and Shadowing OK Best Avoid Avoid
3 Striping with static parity OK OK Avoid Avoid
5 Striping with rotating parity OK Best(*) Avoid Avoid

(*) if RAID0-1 not available

3- You can examine file statistics

--
-- you can check file statistics
--
select
t2.name,
t1.phyrds,
t1.phywrts,
t1.readtim,
t1.writetim
from
v$filestat t1,

16
v$datafile t2
where
t1.file#=t2.file#
order by phyrds desc, phywrts desc;
--
-- temporary statistics
--
select
t2.name,
t1.phyrds,
t1.phywrts,
t1.readtim,
t1.writetim
from
v$tempstat t1,
v$tempfile t2
where
t1.file#=t2.file#
order by phyrds desc, phywrts desc;

4- Consider the following parameters for background processes performance


tuning. More than one dbwr(db writer process can be used)

If not asynchronous IO then


DBWR_IO_SLAVES = [1...9]
Else
DISK_ASYNCH_IO = [ON | OF]
End if

--
-- tuning dbwriter process
--
select * from v$parameter where name like '%dbwr_io_slaves%';
select * from v$parameter where name like '%db_writer_processes%';
select * from v$parameter where name like '%disk_asynch_io%';
--alter system set db_writer_processes=[0...9];
alter system set db_writer_processes=2 scope=spfile;

17
Tuning log_buffer

copy redo latch: Log_simultaneous_copies = n  
redo allocation latch: Log_parallelism=n 
redo writing latch: LGWR handles this instance operation 
--
-- examine log switch frequency
--
select max(to_char(FIRST_TIME,'DD.MM.YYYY HH24')), count(RECID)
from v$log_history
group by to_char(FIRST_TIME,'DD.MM.YYYY HH24')
order by to_char(FIRST_TIME,'DD.MM.YYYY HH24') asc

if the ratio misses to gets exceeds %1 or ratio of immediate_misses to (immediate_gets + 
immediate_misses) exceeds %1 there is a latch contention. First tune the “redo_allocation” 
latch and then “redo_copy” latch. 
-- any latches for log_buffer in memory?
select substr(ln.name,1,20), gets, misses, immediate_gets, immediate_misses
from v$latch l , v$latchname ln
where ln.name in ('redo allocation', 'redo copy')
and ln.latch#=l.latch#;

-- server statistics about redo space requests


select name, value from v$sysstat where name = 'redo log space requests';

--
-- tuning log_buffer parameter
--
select name, value from v$parameter where name='log_buffer';
alter system set log_buffer=1024 scope=spfile;
--alter system set log_buffer = [512*CPU_COUNT]

--
-- parallel log write
--
select name, value from v$parameter where name='log_parallelism';
alter system set log_parallelism=2 scope=spfile;

--
-- is there any session waiting for log buffer space
--
select
sid,
event,
seconds_in_wait ,
state
from
v$session_wait
where
event like '%log buffer space%';
--
-- check the percentage of redo writes and retries
--
-- the pct value should be very close to zero which means system
-- is not retrying for redo buffer allocation
select
t1.value, t2.value,
(t2.value*100)/(t1.value+t2.value) "retries/entries"
from
v$sysstat t1,
v$sysstat t2

18
where
t1.name in ('redo entries') and
t2.name in ('redo buffer allocation retries');

Notes
Redo_allocation_latch
- decrease log_small_entry_max_size
(default redo size/redo entries from v$sysstat)
Redo_copy_latch
- increase _log_simultaneous_copies (default twice the cpu count)
- increase log_buffer

Views
v$session_wait
v$sysstat

Parameters
log_parallelism
log_buffer

Tuning MTTR

show parameter fast_start_mttr_target; --in seconds forces DBWR to write


dirty buffers to disk
select recovery_estimated_ios, actual_redo_blks redo, target_mttr,
estimated_mttr, writes_mttr
from v$instance_recovery;

Oracle Wait Interface (OWI)

--more than 800 wait events grouped for easier maintenance


select wait_class, total_waits, time_waited
from v$system_wait_class order by time_waited;

Oracle wait interface is a group of views that you can use to monitor
waiting events and sessions waiting them.

1- first thing is thinking system wide.

--
-- System wide event waits
--
select * from v$system_event order by total_waits desc;

--
--
--
select * from v$event_name;

2- and then session wide

--
-- Session wide events
--
-- you can see the SID and easily join with v$session
select * from v$session_event order by total_waits desc;

3- time to examine session waits currently

--
-- session wide waits
--

19
-- you can obtain P1, P2 and P3 parameter meanings in v$event_name
select * from v$session_wait order by seconds_in_wait desc;

NOTES
N1- P1, P2 and P3 columns are important in some types of waits. For
example:
If (event_name IN
(‘db file sequential read’ , ‘db file scattered read’))
then
P1 means file#
P2 means block#
P3 means blocks
End If;

--
-- lets find sessions waiting the files
--
select
t1.event,
t1.state,
t1.wait_time,
t1.seconds_in_wait,
t2.username,
t3.name
from
v$session_wait t1,
v$session t2,
v$datafile t3
where
t1.sid = t2.sid and
t1.p1 = t3.file# and
t1.event in ('db file sequential read','db file scattered read');

N2- There are two columns indicationg the waited time. “wait_time” and
“second_in_wait”. You can consider these values by reading “state” column.

If (“state” = WAITING) then


Consider “SECONDS_IN_WAIT”
Else If (“state” = WAITED_KNOWN_TIME) then
Consider “WAIT_TIME”
Else If (“state” = WAITED_UNKNOWN_TIME) then
Alter system set timed_statistics=TRUE -- 
End If

4- you can also examine system wide and session wide statistics

--
-- system statistics
--
select * from v$sysstat;
--
-- session statistics
--
-- you cannot find statistics name in v$sesstat
-- so we have to join with v$statname
select
t1.sid,
t3.username,
t2.name,
t1.value
from
v$sesstat t1,
v$statname t2,
v$session t3

20
where
t1.statistic# = t2.statistic# and
t1.sid = t3.sid and
t3.username is not null;
--
--
--
select * from v$statname;

List of views
v$system_event
System wide wait events.
Values are total waits until system startup.
Wait values are reset every system restart.
v$event_name
Properties of wait events.
v$session_event
Session wide wait events.
Has almost same properties with v$system_event.
There is one mor column for SID.
v$session_wait
Session wide waits, this view gives you the currents waits by
user and resets every session kills itself.

v$latch
v$latchname
v$enqueue

v$sysstat
v$sesstat
v$filestat
v$tempstat
v$sgastat
v$pgastat
v$statname

parameters
timed_statistics
statistics_level

some of the important wait events (non idle wait events)


buffer busy waits
db file scattered read
db file sequential read
enqueue
free buffer waits
latch free
log file parallel write
log file sync
NOTES
These kind of events points:
Inefficient sql.
Inefficient system architecture.
Inproper instance confugiration.

some of the idle events (can be ignored most of the times)


NULL
SQL*NET Message
Rdbms ipc message
Pmon timer
Pipe get

21
Smon timer

NOTES
Not an indiaction of performance problem.

Some of the important statistics


bytes received via SQL*Net from client
bytes sent via SQL*Net to client
consistent gets --consistent gets+db block gets =
logical IO
db block gets
process last non-idle time
physical reads --physical IO
redo size --redo produced by that session
sorts (disk)
sorts (memory)
SQL*Net roundtrips to/from client

22
Statspack Reports

/*
When installing the Statspack package, you can either change to the
ORACLE_HOME/rdbms/admin directory, or fully specify the
ORACLE_HOME/rdbms/admin DIRECTORY WHEN calling the installation script,
SPCREATE.SQL.
*/
-- install statspack
@?/rdbms/ADMIN/spcreate

/*
Enter appropriate information when prompted for the PERFSTAT user's
password, default tablespace, and temporary tablespace.
The SPCREATE.SQL install script runs the following scripts automatically:
*/

/*
SPCUSR.SQL: Creates the user and grants privileges
SPCTAB.SQL: Creates the tables
SPCPKG.SQL: Creates the package
*/

-- To install without prompting


SQL> CONNECT / AS SYSDBA
SQL> define default_tablespace='TOOLS'
SQL> define temporary_tablespace='TEMP'
SQL> define perfstat_password='my_perfstat_password'
SQL> @?/rdbms/ADMIN/spcreate
/*
-- automatic collection of statistics
oracle_home/rdbms/admin/spauto.sql
*/
-- executing statspack
SQL> CONNECT perfstat/my_perfstat_password
SQL> EXECUTE statspack.snap;
-- For better performance analysis, set the initialization parameter
TIMED_STATISTICS to TRUE.
-- Statspack will then include important timing information in the data it
collects.

-- create statspack report


SQL> CONNECT perfstat/my_perfstat_password
SQL> @?/rdbms/ADMIN/spreport
-- statspack in a pl/sql block
DECLARE
variable snap NUMBER;
BEGIN
snap := statspack.snap;
dbms_output.put_line(snap);
END;
-- automatic statspac
-- A sample script on how to do this is supplied in SPAUTO.SQL
-- create statspack report without prompt
SQL> CONNECT perfstat/my_perfstat_password
SQL> define begin_snap=1
SQL> define end_snap=2
SQL> define report_name=batch_run
SQL> @?/rdbms/ADMIN/spreport

23
/*
When you examine the instance report, you often find high-load SQL
statements that you want to examine more closely. The SQL report,
SPREPSQL.SQL, displays statistics, the complete SQL text, and (if a level
six snapshot has been taken), information on any SQL plan(s) associated
with that statement.
*/
SQL> CONNECT perfstat/my_perfstat_password
Connected.
SQL> @?/rdbms/ADMIN/sprepsql
-- truncate all statspack data
SQL> CONNECT perfstat/my_perfstat_password
SQL> @?/rdbms/ADMIN/sptrunc
-- remove statspack
SQL> CONNECT / AS SYSDBA
SQL> @?/rdbms/ADMIN/spdrop

/*
SPDTAB.SQL - drops tables and public synonyms
SPDUSR.SQL - drops the user
*/
-- Purge unnecessary data by using the SPPURGE.SQL script
SQL> CONNECT perfstat/my_perfstat_password
SQL> SET TRANSACTION USE ROLLBACK SEGMENT rbig;
SQL> @?/rdbms/admin/sppurge
SQL> CONNECT perfstat/my_perfstat_password
SQL> DEFINE losnapid=1
SQL> DEFINE hisnapid=2
SQL> @?/rdbms/admin/sppurge

-- snap parameters
EXECUTE STATSPACK.SNAP(i_ucomment=>'this is a temporary commment');
EXECUTE STATSPACK.MODIFY_STATSPACK_PARAMETER(i_ucomment=>'this is a
commment that is saved');
EXECUTE STATSPACK.SNAP(i_snap_level=>10, i_modify_parameter=>'true');
EXECUTE STATSPACK.SNAP(i_snap_level=>6);
Levels >= 0 General Performance STATISTICS
Levels >= 5 Additional Data: SQL Statements
Levels >= 6 Additional Data: SQL Plans AND SQL PLAN Usage
Levels >= 7 Additional data: SEGMENT LEVEL STATISTICS
Levels >= 10 Additional STATISTICS: Parent AND Child Latches

24
Some 10g enhancements

sga_target

sga_target init parameter is introduced with 10g AMM (Automatic Memory


Management). To disable sga_target just assign “0” to the parameter. Is
sga_target is assigned any different value than “0” then DB_CACHE_SIZE,
SHARED_POOL_SIZE, LARGE_POOL_SIZE, JAVA_POOL_SIZE, STREAMS_POOL_SIZE are
automatically sized. If you assign any values to these parameter then that
value will be the low limit of that pool.

Log_buffer, KEEP and RECYCYCLE cache’s do not affect from AMM.

--
-- sga_taget parameter
--
-- disabling sga_target parameter
alter system set sga_target=0 scope=spfile;
-- enabling sga_target parameter
alter system set sga_target=128M scope=spfile;

MetaLink Note:295626.1, How To Use Automatic Shared Memory Management


(ASMM) In Oracle10g, has some script for monitoring Oracle Automatic Shared
Memory Management:

select
component,
oper_type,
oper_mode,
initial_size/1024/1024 "Initial",
TARGET_SIZE/1024/1024 "Target",
FINAL_SIZE/1024/1024 "Final",
status
from
v$sga_resize_ops;
COMPONENT OPER_TYPE OPER_MODE INITIAL TARGET FINAL STATUS
------------------------------ ------------- --------- ---------- ---------- ---------- ---------
DEFAULT buffer cache SHRINK MANUAL 160 148 148 COMPLETE
streams pool GROW MANUAL 0 12 12 COMPLETE

select
component,
current_size/1024/1024 "CURRENT_SIZE",
min_size/1024/1024 "MIN_SIZE",
user_specified_size/1024/1024 "USER_SPECIFIED_SIZE",
last_oper_type "TYPE"
from
v$sga_dynamic_components;
COMPONENT CURRENT_SIZE MIN_SIZE USER_SPECIFIED_SIZE TYPE
------------------------------ ------------ ---------- ------------------- -------------
shared pool 80 80 80 STATIC
large pool 8 8 8 STATIC
java pool 4 8 48 48 STATIC
streams pool 12 0 12 GROW
DEFAULT buffer cache 48 24 24 SHRINK
KEEP buffer cache 0 0 0 STATIC
RECYCLE buffer cache 0 0 0 STATIC
DEFAULT 2K buffer cache 0 0 0 STATIC
DEFAULT 4K buffer cache 0 0 0 STATIC
DEFAULT 8K buffer cache 0 0 0 STATIC
DEFAULT 16K buffer cache 0 0 0 STATIC
DEFAULT 32K buffer cache 0 0 0 STATIC
OSM Buffer Cache 0 0 24 STATIC

select sum(value) from v$sga;


select sum(bytes) from v$sgastat;

25
select sum(current_size) from v$sga_dynamic_components;
select * from v$sga_dynamic_free_memory;

new advisories

new advice views are added to v$db_cache_advice, v$shared_pool_advice and


v$pga_target_advice. These are;

dba_hist_db_cache_advice
dba_hist_shared_pool_advice
dba_hist_pga_target_advice

after 10g you can track advice histograms by using these views.

sql tuning advisor (optimizer statistics, sql profiling, access path


analysis, sql structure analysis)
sql access advisor (additional indexes, materialized views)
memory advisor (shared pool, db buffer cache, PGA)
MMTR advisor
segment advisor (whether a segment should be shrunk)
undo advisor

Automatic managements

AWR: automatic workload repository


ASH: automatic session history
AMM: automatic memory management
ASM: automatic storage management

dbms_monitor

dbms_monitor system package can be used instead of 10046 dumps. AWR and ASH
automatically tracks all current waits and interfaces.

-- background process mmon flushes the statistics to disk in a regular


basis.
-- ts is SYSAUX that make up Automatic Workload Repository.
-- every snapshot also invokes ADDM

-- defaults are 1 week and 1 hour


execute dbms_workload_repository.modify_snapshot_settings
(
retention=>20160, --2 weeks
interval=>20 --20 minutes
);

26

You might also like