You are on page 1of 47

Oracle Performance Tuning

ss

Beacon Infotech Corporation


www.oracleact.com

Tamilselvan G
Be
In ac
Co f o t o n
rp ech
or
at
io
n

a
Cl

-3

2007-12-25

Oracle Performance Tuning


Statistics Collection and Tkprof
1.
2.
3.
4.

Beacon Infotech Corporation


www.oracleact.com

Optimizer Statistics
Generating Extended Trace Data
Trace file Walk Through
Tkprof

2007-12-25

Oracle Performance Tuning


Understanding Statistics in 10g

1. Optimizer Statistics

Optimizer statistics are a collection of data that describe more details


about the database and the objects in the database.
They include the following:
1.

Table Statistics ( # of rows, # of blocks, average row length)

2.

Column Statistics ( # of distinct values in a column, # of nulls, data distribution


(Histogram) )

3.

Index Statistics (# of leaf blocks, Levels, Clustering Factor)

4.

System Statistics (IO performance and utilization and CPU performance and
Utilization)

Statistics are maintained automatically by


Oracle 10g or you can maintain the
optimizer statistics manually using the
DBMS_STATS package.
Beacon Infotech Corporation
www.oracleact.com

2007-12-25

Oracle Performance Tuning


1. Optimizer Statistics
Automatic Statistics Gathering in 10g
Oracle gathers statistics on all database objects automatically and
maintains those statistics in a regularly-scheduled maintenance job
(GATHER_STATS_JOB).
This job is created automatically at database creation time and is
managed by the Scheduler. The Scheduler runs this job when the
maintenance window is opened. By default, the maintenance window
opens every night from 10 P.M. to 6 A.M. and all day on weekends.
DBMS_SCHEDULER package has more features than DBMS_JOB.
Example, now you can execute a OS job with in DBMS_SCHEDULER.
You can verify that the job exists by viewing the DBA_SCHEDULER_JOBS view:

SELECT * FROM DBA_SCHEDULER_JOBS


WHERE JOB_NAME = 'GATHER_STATS_JOB';

Beacon Infotech Corporation


www.oracleact.com

2007-12-25

Oracle Performance Tuning


Manual Statistics Gathering

1. Optimizer Statistics

If you choose not to use automatic statistics gathering, then you need to
manually collect statistics in all schemas, including sys and system schemas.
Statistics are gathered using the DBMS_STATS package. This PL/SQL
package is also used to modify, view, export, import, and delete statistics.
#
1

Procedure
GATHER_INDEX_STATS

Collects
Index Statistics

GATHER_TABLE_STATS

Table, Index, Column Statistics

GATHER_SCHEMA_STATS

Statistics for all objects in a Schema

GATHER_DICTIONARY_STATS

Statistics for all dictionary objects

GATHER_DATABASE_STATS

Statistics for all objects in a database

GATHER_FIXED_OBJECTS_STATS

GATHER_SYSTEM_STATS

Statistics for all fixed objects (dynamic


performance tables).
Statistics for IO and CPU

Beacon Infotech Corporation


www.oracleact.com

2007-12-25

Oracle Performance Tuning


Manual Statistics Gathering

1. Optimizer Statistics

SET_PARAM Procedure
This procedure sets default values for parameters of DBMS_STATS procedures. You
can use the GET_PARAM Function to get the current default value of a parameter.
Syntax
DBMS_STATS.SET_PARAM ( pname IN VARCHAR2, pval IN VARCHAR2);
Pname

Pval

The parameter name The default value for following


parameters can be set.
CASCADE - The default value for CASCADE set by
SET_PARAM is not used by export/import
procedures.It is used only by gather procedures.
DEGREE
ESTIMATE_PERCENT
METHOD_OPT
NO_INVALIDATE
GRANULARITY
AUTOSTATS_TARGET - This parameter is applicable
only for auto statistics collection. The value of this
parameter controls the objects considered for
statistics collection (see pval)

The parameter value. If NULL is specified, it will set


the default value determined by Oracle. When pname
is AUTOSTATS_TARGET, the following are valid
values:
'ALL' - Statistics are collected for all objects in the
system
'ORACLE' - Statistics are collected for all Oracle
owned objects
'AUTO' - Oracle decides for which objects to collect
statistics

Beacon Infotech Corporation


www.oracleact.com

2007-12-25

Oracle Performance Tuning


Manual Statistics Gathering

1. Optimizer Statistics

SET_PARAM Procedure
Example:
SQL> exec dbms_stats.set_param('ESTIMATE_PERCENT','10') ; -- To change estimate percentage
PL/SQL procedure successfully completed.
SQL> exec dbms_stats.set_param('DEGREE','8'); ---- To change degree of parallelism

PL/SQL procedure successfully completed.


SQL> exec dbms_stats.set_param('CASCADE','DBMS_STATS.AUTO_CASCADE');
PL/SQL procedure successfully completed.

Beacon Infotech Corporation


www.oracleact.com

2007-12-25

Oracle Performance Tuning


1. Optimizer Statistics
Manual Statistics Gathering - DBMS_STATS.GATHER_INDEX_STATS
This procedure gathers index statistics. It attempts to parallelize as much of the
work as possible. Restrictions are described in the individual parameters. This
operation will not parallelize with certain types of indexes, including cluster
indexes, domain indexes, and bitmap join indexes.
Example:
begin
sys.dbms_stats.gather_index_stats(
ownname => USER ,
indname => 'SALE_IDX',
estimate_percent => 60,
degree => 8 ,
granularity => 'ALL );
end;
/

Note: 1. When I tried to use FORCE parameter with a value TRUE, I get an error. Check
with your release. The FORCE parameter if set to TRUE will allow the procedure to
gather statistics even if the objects statistics is locked.
2. In 10g Oracle automatically gathers statistics when CREATE INDEX
command is used.
Beacon Infotech Corporation
www.oracleact.com

2007-12-25

Oracle Performance Tuning


1. Optimizer Statistics
Manual Statistics Gathering - DBMS_STATS.GATHER_TABLE_STATS
This procedure gathers table and column (and index) statistics. It attempts to
parallelize as much of the work as possible.
Example:
begin
sys.dbms_stats.gather_table_stats(
ownname
=> USER ,
tabname
=> 'SALES',
estimate_percent => 10,
degree
=> 8 ,
granularity
=> 'ALL',
cascade
=> TRUE,
method_opt
=> 'FOR COLUMNS INV_NUM SIZE 1, PRODUCT_ID SIZE 200, CUST_ID SIZE 100'
);
Histogram : There are 4 values you can set for collecting histogram.
end;
They are integer, REPEAT, AUTO and SKEWONLY.
/

Note: Additional Parameters


BLOCKSAMPLE Whether or not to use random block sampling instead of random row sampling. Random block
sampling is more efficient, but if the data is not randomly distributed on disk, then the sample
values may be somewhat correlated. Only pertinent when doing an estimate statistics

STATTAB
STATID
STATOWN
Beacon Infotech Corporation
www.oracleact.com

User statistics table identifier describing where to save the current statistics
Identifier (optional) to associate with these statistics within stattab
Schema containing stattab (if different than ownname)

2007-12-25

Oracle Performance Tuning


1. Optimizer Statistics
Manual Statistics Gathering - DBMS_STATS.GATHER_SCHEMA_STATS
This procedure gathers statistics for all objects in a schema.
DBMS_STATS.GATHER_SCHEMA_STATS (
ownname
VARCHAR2,
estimate_percent
NUMBER DEFAULT to_estimate_percent_type (get_param('ESTIMATE_PERCENT')),
block_sample
BOOLEAN DEFAULT FALSE,
method_opt
VARCHAR2 DEFAULT get_param('METHOD_OPT'),
degree
NUMBER DEFAULT to_degree_type(get_param('DEGREE')),
granularity
VARCHAR2 DEFAULT GET_PARAM('GRANULARITY'),
cascade
BOOLEAN DEFAULT to_cascade_type(get_param('CASCADE')),
stattab
VARCHAR2 DEFAULT NULL,
statid
VARCHAR2 DEFAULT NULL,
options
VARCHAR2 DEFAULT 'GATHER',
objlist
OUT ObjectTab, statown VARCHAR2 DEFAULT NULL,
no_invalidate
BOOLEAN DEFAULT to_no_invalidate_type ( get_param('NO_INVALIDATE')),
force
BOOLEAN DEFAULT FALSE);
Example:

begin dbms_stats.gather_schema_stats(
ownname => TAMIL',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size skewonly',
degree => 7 );
end;
/ Infotech Corporation
Beacon
www.oracleact.com

10

2007-12-25

Oracle Performance Tuning


1. Optimizer Statistics
Manual Statistics Gathering - DBMS_STATS.GATHER_DICTIONARY_STATS
This procedure gathers statistics for dictionary schemas 'SYS', 'SYSTEM' and schemas of
RDBMS components.
DBMS_STATS.GATHER_DICTIONARY_STATS (
compid
VARCHAR2 DEFAULT NULL,
estimate_percent
NUMBER DEFAULT to_estimate_percent_type (get_param('ESTIMATE_PERCENT')),
block_sample
BOOLEAN DEFAULT FALSE,
method_opt
VARCHAR2 DEFAULT get_param('METHOD_OPT'),
degree
NUMBER DEFAULT to_degree_type(get_param('DEGREE')),
granularity
VARCHAR2 DEFAULT GET_PARAM('GRANULARITY'),
cascade
BOOLEAN DEFAULT to_cascade_type(get_param('CASCADE')),
stattab
VARCHAR2 DEFAULT NULL,
statid
VARCHAR2 DEFAULT NULL,
options
VARCHAR2 DEFAULT 'GATHER',
objlist
OUT ObjectTab, statown VARCHAR2 DEFAULT NULL,
no_invalidate
BOOLEAN DEFAULT to_no_invalidate_type ( get_param('NO_INVALIDATE')),
);

Note:The component id of the schema to analyze (NULL will result in analyzing schemas of all
RDBMS components). Please refer to comp_id column of DBA_REGISTRY view. The procedure
always gather statistics on 'SYS' and 'SYSTEM' schemas regardless of this argument.
Example: exec DBMS_STATS.GATHER_DICTIONARY_STATS ;

PL/SQL procedure successfully completed


Beacon Infotech Corporation
www.oracleact.com

11

2007-12-25

Oracle Performance Tuning


1. Optimizer Statistics
Manual Statistics Gathering - DBMS_STATS.GATHER_DATABSE_STATS
This procedure gathers statistics for all objects in the database.
DBMS_STATS.GATHER_DATABASE_STATS (
estimate_percent

NUMBER DEFAULT to_estimate_percent_type (get_param( ESTIMATE_PERCENT')),

block_sample
method_opt
degree
granularity
cascade
stattab
statid
options
objlist
statown
gather_sys
no_invalidate

BOOLEAN DEFAULT FALSE, .


VARCHAR2 DEFAULT get_param('METHOD_OPT'),
NUMBER DEFAULT to_degree_type(get_param('DEGREE')),
VARCHAR2 DEFAULT GET_PARAM('GRANULARITY'),
BOOLEAN DEFAULT to_cascade_type(get_param('CASCADE')),
VARCHAR2 DEFAULT NULL,
VARCHAR2 DEFAULT NULL,
VARCHAR2 DEFAULT 'GATHER',
OUT ObjectTab,
VARCHAR2 DEFAULT NULL,
BOOLEAN DEFAULT TRUE,
BOOLEAN DEFAULT to_no_invalidate_type ( get_param('NO_INVALIDATE')));

Example in :
SQL> begin
dbms_stats.gather_database_stats( estimate_percent => 2, degree => 8);
end;
/
PL/SQL procedure successfully completed.
Beacon Infotech Corporation
www.oracleact.com

12

2007-12-25

Oracle Performance Tuning


1. Optimizer Statistics
Manual Statistics Gathering- DBMS_STATS.GATHER_DIXED_OBJECTS_STATS
This procedure gathers statistics for all fixed objects (dynamic performance tables).
DBMS_STATS.GATHER_FIXED_OBJECTS_STATS (
stattab
VARCHAR2 DEFAULT NULL,
statid
VARCHAR2 DEFAULT NULL,
statown
VARCHAR2 DEFAULT NULL,
no_invalidate
BOOLEAN DEFAULT to_no_invalidate_type (get_param('NO_INVALIDATE')));
Where
Stattab
The user statistics table identifier describing where to save the current statistics
Statid
The (optional) identifier to associate with these statistics within stattab
Statown
Schema containing stattab (if different from current schema)
no_invalidate Does not invalidate the dependent cursors if set to TRUE. The procedure invalidates the
dependent cursors immediately if set to FALSE. Use DBMS_STATS.AUTO_INVALIDATE.
have Oracle decide when to invalidate
dependent cursors. This is the default. The
default can be changed using the SET_PARAM Procedure.

to

Example:
SQL> exec dbms_stats.gather_fixed_objects_stats;
PL/SQL procedure successfully completed.

Beacon Infotech Corporation


www.oracleact.com

13

2007-12-25

Oracle Performance Tuning


1. Optimizer Statistics
Manual Statistics Gathering- DBMS_STATS.GATHER_SYSTEM_STATS
This procedure gathers system statistics.
DBMS_STATS.GATHER_SYSTEM_STATS (
gathering_mode
VARCHAR2 DEFAULT 'NOWORKLOAD',
interval
INTEGER DEFAULT NULL,
stattab
VARCHAR2 DEFAULT NULL,
statid
VARCHAR2 DEFAULT NULL,
statown
VARCHAR2 DEFAULT NULL);
Where
gathering_mode Mode values are: NOWORKLOAD or INTERVAL (START OR STOP)
Collected components: maxthr, slavethr, cpuspeed, sreadtim, mreadtim, mbrc.
Interval Time, in minutes, to gather statistics. This parameter applies only when
gathering_mode='INTERVAL
Stattab Identifier of the user statistics table where the statistics will be saved
Statid
Optional identifier associated with the statistics saved in the stattab
Statown Schema containing stattab (if different from current schema)

Beacon Infotech Corporation


www.oracleact.com

14

2007-12-25

Oracle Performance Tuning


1. Optimizer Statistics
Manual Statistics Gathering- DBMS_STATS.GATHER_SYSTEM_STATS
Step 1
First Create a table to store the statistics

Step 2
Start collecting Statistics

SQL> begin
dbms_stats.create_stat_table(
ownname => 'SYS',
stattab => 'TAMIL_SYSTEM_STATS',
tblspace => 'USERS');
end;
/

SQL> begin
2 dbms_stats.gather_system_stats(
3
'START', 5, 'TAMIL_SYSTEM_STATS',
'OLTP', 'SYS');
4 end;
5 /

Step 3
Execute some scripts for some duration.

Step 4
Stop Collecting SYSTEM Stats

SQL> select count(*) from dba_objects;

SQL> begin
2 dbms_stats.gather_system_stats(
3 'STOP', 5, 'TAMIL_SYSTEM_STATS',
'OLTP', 'SYS');
4 end;
5 /

COUNT(*)
---------43822
Beacon Infotech Corporation
www.oracleact.com

15

2007-12-25

Oracle Performance Tuning 2. Generating Extended Trace Data


Parameters affecting trace data
SQL> alter session set events
'10046 trace name context forever, level 8 ' ;

1.
2.
3.

TIMED_STATISTICS must be set TRUE.


MAX_DUMP_FILE_SIZE must be set to a high
value (measured in OS blocks) or unlimited.
Optional parameter TRACEFILE_IDENTIFIER
can be set to a string at the session level.

Session altered.
SQL> select count(*) from user_objects ;
COUNT(*)
---------94

Example:
SQL> alter session set timed_statistics = true ;
Session altered.

SQL> alter session set events


'10046 trace name context off';

SQL> alter session set max_dump_file_size = 100000000;


Session altered.

Session altered.

SQL> alter session set tracefile_identifier = 'tamil_trace' ;


SQL> exit
Session altered.

hostname:SID=ORDBA=>ls -lrt *tamil*


-rw-r--r-- 1 oracle dba
Beacon Infotech Corporation
www.oracleact.com

79152 May 7 11:12 ordba_ora_27853_tamil_trace.trc

16

2007-12-25

Oracle Performance Tuning 2. Generating Extended Trace Data


Options to generate extended trace data
#

COMMAND

Comments

ALTER SESSION SET SQL_TRACE = TRUE ;


/* execute your code */
ALTER SESSION SET SQL_TRACE = FALSE ;

-- To Turn on tracing

COMMIT;

In some release of Oracle ROW


SOURCE info will not be generated,
the commit will ensure that STAT
Lines get written in the trace data.

Alter session set events 10046 trace name context forever,


level x ;

Where X can have the following values:


0 Tracing is disabled
1 Default level; Equivalent to SQL_TRACE
= true
4 Provides BIND variables values
8 - Provides WAIT events
12 Provides both BIND variables values
and WAIT events
To Turn off tracing

-- To Turn off tracing

/* Execute your code */

Alter session set events 10046 trace name context off ;

Beacon Infotech Corporation


www.oracleact.com

17

2007-12-25

Oracle Performance Tuning 2. Generating Extended Trace Data


Options to generate extended trace data
#

COMMAND

Comments

In init.ora file:
EVENT = 10046 trace name context forever, level 8;

At instance level, enables the trace


event.

DBMS_SUPPORT package to trace your session.

Enabling WAIT events, and BIND Variables


using dbms_support.

SQL> exec sys.dbms_support.start_trace ;


SQL> exec
sys.dbms_support.start_trace(waits =>true,
binds=> true);

PL/SQL procedure successfully completed.


SQL> select count(*) from emp;
COUNT(*)
---------5
SQL> exec sys.dbms_support.stop_trace ;
PL/SQL procedure successfully completed.

Beacon Infotech Corporation


www.oracleact.com

18

2007-12-25

Oracle Performance Tuning 2. Generating Extended Trace Data


Options to generate extended trace data
#

COMMAND

Comments

How to trace someone elses session


SQL> exec
sys.dbms_system.SET_BOOL_PARAM_IN_SESSION(16,
181, 'sql_trace', TRUE);
SQL> exec
sys.dbms_system.SET_BOOL_PARAM_IN_SESSION(16,
181, 'sql_trace', FALSE);

Where 16 is SID and 181 is


Serial# obtained from
V$SESSION.
To turn on tracing

SQL> exec dbms_system.set_sql_trace_in_session(448,2288,TRUE);

Turn SQL tracing on in session


448 (SID) and 2288 (Serial#)

SQL> exec dbms_system.set_sql_trace_in_session(448,2288,FALSE);

Turn SQL tracing off in session


448

SQL> exec dbms_system.set_ev(8, 1158, 10046, 12, '');


Where 8 is SID, and 1158 is the Serial#.

Set event 10046


(SQL_TRACE) at level 12 to
collect information about all
wait events and bind
variables. The trace
information will get written
to user_dump_dest.

SQL> exec dbms_system.set_ev(8, 1158, 10046, 0, '');


Will stop tracing
Beacon Infotech Corporation
www.oracleact.com

19

To Turn off tracing

2007-12-25

Oracle Performance Tuning 2. Generating Extended Trace Data


Options to generate extended trace data
#

COMMAND

Comments

Using DBMS_MONITOR Package


Start tracing the session
100, serial# 482
exec sys.dbms_monitor.session_trace_enable(
session_id=>100,serial_num=>482, waits=>true,
binds=>true);
/* Execute your SQL script */
exec sys.dbms_monitor.session_trace_disable(
session_id=>100,serial_num=>482);

Beacon Infotech Corporation


www.oracleact.com

20

Stop tracing

2007-12-25

Oracle Performance Tuning 2. Generating Extended Trace Data


Options to generate extended trace data
#

COMMAND

Using oradebug

Comments

SQL> select p.spid, s.paddr, s.sid, s.serial#, p.addr


from v$session s, v$process p
where s.username = 'TAMIL' and s.paddr = p.addr ;
SPID
PADDR
SID SERIAL# ADDR
------------ ---------------- ---------- ---------- ---------------1369
0000000398F69D40
95
4 0000000398F69D40
SQL> oradebug setospid 1369

You need to login as SYS to


execute oradebug command.

Oracle pid: 20, Unix process pid: 1369, image: oracle@hostname (TNS V1-V3)

SQL> oradebug event 10046 trace name context forever, level 12;
Statement processed.

In another user session,


execute the SQL script

SQL> oradebug event 10046 trace name context off ;


Statement processed.
Beacon Infotech Corporation
www.oracleact.com

21

2007-12-25

Oracle Performance Tuning 2. Generating Extended Trace Data


Options to generate extended trace data
#

COMMAND

Comments

10

LOGON Trigger

This is my favorite
method to generate
trace data on some one
elses code.

create or replace trigger user_logon_trg


after logon on database
begin
if USER = 'TAMIL' then
execute immediate
'alter session set events ''10046 trace name context forever, level 8''';
end if;
end;
/

LOGOFF Trigger
create or replace trigger user_logoff_trg
before logoff on database
begin
if USER = 'TAMIL' then
execute immediate
'alter session set events ''10046 trace name context off';
end if;
end;
/

Beacon Infotech Corporation


www.oracleact.com

22

Always use IF USER


check or
SYS_CONTEXT('USERENV'
,'SESSION_USER'),
otherwise, the file system
will be run out of space.

2007-12-25

Oracle Performance Tuning 2. Generating Extended Trace Data


Options to generate extended trace data
#

COMMAND

Comments

11

Using DBMS_MONITOR

New feature
in 10g for
tracing a
user session.

DBMS_MONITOR.SERV_MOD_ACT_TRACE_ENABLE(
service_name IN VARCHAR2,
module_name IN VARCHAR2 DEFAULT ANY_MODULE,
action_name IN VARCHAR2 DEFAULT ANY_ACTION,
waits
IN BOOLEAN DEFAULT TRUE,
binds
IN BOOLEAN DEFAULT FALSE,
instance_name IN VARCHAR2 DEFAULT NULL);
DBMS_MONITOR.SERV_MOD_ACT_TRACE_DISABLE(
service_name IN VARCHAR2,
module_name IN VARCHAR2,
action_name
IN VARCHAR2 DEFAULT ALL_ACTIONS,
instance_name IN VARCHAR2 DEFAULT NULL);

You can also set module name, action name using


DBMS_APPLICATION_INFO package within your
application code.
Beacon Infotech Corporation
www.oracleact.com

23

2007-12-25

Oracle Performance Tuning 2. Generating Extended Trace Data


Options to generate extended trace data
#

COMMAND

11

Using DBMS_MONITOR

Comments

SQL> select username, service_name, module, action , sid


from V$SESSION where username='TAMIL';
USERNAME SERVICE_NAME MODULE
---------------- ---------------------TAMIL
ORDBA
SQL*Plus

ACTION SID
----------------107

SQL> begin
dbms_monitor.serv_mod_act_trace_enable
('ORDBA', 'SQL*Plus',
DBMS_MONITOR.ALL_ACTIONS, TRUE, TRUE, NULL);
end;
/
PL/SQL procedure successfully completed.
SQL> select /* test dbms monitor */ count(1) from emp ;
COUNT(1)
---------5

To disable tracing,
use dbms_monitor.serv_mod_act_trace_disable procedure.
Beacon Infotech Corporation
www.oracleact.com

24

2007-12-25

Oracle Performance Tuning 3. Trace File Walk Through


Let us study a level-12 trace file in details
1 Dump file /u12/ORDBA/admin/udump/ordba_ora_19186.trc
2 Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - 64bit Production
3 With the Partitioning, OLAP and Data Mining options
4 ORACLE_HOME = /uo1/oracle/product/10.1.0
5 System name: SunOS
6 Node name:
hostname
7 Release:
5.8
8 Version:
Generic_117350-28
9 Machine:
sun4u
10 Instance name: ORDBA
11 Redo thread mounted by this instance: 1
12 Oracle process number: 18
13 Unix process pid: 19186, image: oracle@hostname (TNS V1-V3)
14
15 *** ACTION NAME:() 2006-05-07 17:09:13.681
16 *** MODULE NAME:(SQL*Plus) 2006-05-07 17:09:13.681
17 *** SERVICE NAME:(SYS$USERS) 2006-05-07 17:09:13.681
18 *** SESSION ID:(100.46) 2006-05-07 17:09:13.680
19 =====================

Beacon Infotech Corporation


www.oracleact.com

25

2007-12-25

Oracle Performance Tuning 3. Trace File Walk Through.


20 PARSING IN CURSOR #2 len=70 dep=0 uid=45 oct=42 lid=45 tim=51148583752 hv=3349967750 ad='939d7ff0'
21 alter session set events '10046 trace name context forever, level 12'
22 END OF STMT
23 EXEC #2:c=0,e=509,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=51148583653
24 WAIT #2: nam='SQL*Net message to client' ela= 5 p1=1650815232 p2=1 p3=0
25 WAIT #2: nam='SQL*Net message from client' ela= 1841 p1=1650815232 p2=1 p3=0
26 =====================

Kernel identifies every SQL statement used by the session in a PARSING IN CURSOR section.
Oracle opened a cursor # 2 for setting up the trace event 10046.
The END OF STMT line indicates end of SQL statement.

Beacon Infotech Corporation


www.oracleact.com

26

2007-12-25

Oracle Performance Tuning 3. Trace File Walk Through.


27 PARSING IN CURSOR #1 len=466 dep=0 uid=45 oct=3 lid=45 tim=51148592687 hv=3957042544 ad='939efad0'
28 select a.state,
29
c.product_cat ,
30
sum(b.sale_qty),
31
sum(b.sale_amt)
32 from customer a, sales b, product c
33 where a.cust_id = b.cust_id and
34
b.product_id = c.product_id and
35
b.sale_date between to_date('01/01/2004 00:00:00', 'MM/DD/YYYY HH24:MI:SS')
36
and to_date('12/31/2004 23:59:59', 'MM/DD/YYYY HH24:MI:SS') and
37
c.product_cat = :b1 and
38
a.state in ('GA','TX','SC')
39 group by a.state, c.product_cat
40 END OF STMT
Let us study more in details in line 27.
Cursor # is 1
len = length of the SQL statement (in our case it is 466 characters)
dep - recursive depth of the cursor. A dep = n+1 cursor is a child of some dep=n cursor (n = 0,1,2,3)
uid = the schema user id of the user who parsed the statement
oct = Oracle command type ID
lid = the privilege user id
tim = in 9i and 10g it is expressed in Microseconds, if its zero then TIMED_STATISTICS is set to FALSE
hv = Statement ID of the SQL statement. It is not unique.
ad = the library cache address as shown in V$SQL

Beacon Infotech Corporation


www.oracleact.com

27

2007-12-25

Oracle Performance Tuning 3. Trace File Walk Through


41
42
43
44
45
46

PARSE #1:c=0,e=442,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=51,148,592,669
BINDS #1:
bind 0: dty=1 mxl=32(30) mal=00 scl=00 pre=00 oacflg=03 oacfl2=0010 size=32 offset=0
bfp=ffffffff7bb65368 bln=32 avl=02 flg=05
value="TV
EXEC #1:c=10000,e=1408,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=51,148,595,144

Database Calls
A database call is a sub routine in the Oracle kernel.
PARSE, EXEC, FTECH, ERROR, UNMAP, SORT UNMAP are the most common types of calls.
Let us study line 41 & 46
c = total CPU time consumed by the Oracle process during the call
e = the amount of wall clock time that elapsed during the call
p = the number of physical Oracle database blocks reads
cr = the number of Oracle database blocks obtained in consistent mode from the buffer cache
or undo blocks
cu = the number of Oracle database blocks in current mode from the buffer cache
mis = the number of library cache misses during the call, if its non-zero, then it motivates hard parse
r = the number of rows returned by the call
dep = recursive depth of the cursor
og = optimizer goal ( 1 = ALL ROWS, 2 = FIRST_ROWS, 3 = RULE, 4 = CHOOSE)
tim = a value expressed in microseconds
Notice the error in tim values between two subsequent values, 51,148,592,669 and 51,148,595,144.
51,148,592,669+ 1408 is not equal to 51,148,595,144. The error is 1067 micro seconds.
Beacon Infotech Corporation
www.oracleact.com

28

2007-12-25

Oracle Performance Tuning 3. Trace File Walk Through.


47 WAIT #1: nam='SQL*Net message to client' ela= 3 p1=1650815232 p2=1 p3=0
48 WAIT #1: nam='db file sequential read' ela= 107 p1=7 p2=52510 p3=1
49 WAIT #1: nam='db file scattered read' ela= 874 p1=7 p2=52511 p3=16
50 WAIT #1: nam='db file scattered read' ela= 752 p1=7 p2=52527 p3=16

WAIT EVENTS
When a wait event completes and level-8 or level-12 SQL tracing is active, then Oracle emits a WAIT line upon
competition of that event.
In line 47 the #2 is the cursor number.
nam = Name reveals which part of the kernel code is responsible for the portion of your response time
There are 808 WAIT EVENTS in 10g.
ela = The elapsed time in microseconds in 9i/10g, in cent seconds prior to 9i.
p1,p2, p3 = The meaning differs by nam.
select name, PARAMETER1, PARAMETER2, PARAMETER3, WAIT_CLASS
from v$event_name where PARAMETER1 is not null

Note: Wait events are not the same as WAIT TIME (Queueing delay)
with respect to Queueing Theory.

Beacon Infotech Corporation


www.oracleact.com

29

2007-12-25

Oracle Performance Tuning 3. Trace File Walk Through.


52 WAIT #1: nam='db file scattered read' ela= 719 p1=7 p2=52559 p3=16
..

Lines 53 to 441 are deleted. They are all WAIT events


442
443
444
445
446
447
448
449
450
451
452
453
454
455

WAIT #1: nam='db file scattered read' ela= 591 p1=4 p2=8475 p3=13
FETCH #1:c=1570000,e=1535135,p=6228,cr=6204,cu=0,mis=0,r=1,dep=0,og=1,tim=51150130789
WAIT #1: nam='SQL*Net message from client' ela= 1532 p1=1650815232 p2=1 p3=0
WAIT #1: nam='SQL*Net message to client' ela= 6 p1=1650815232 p2=1 p3=0
FETCH #1:c=0,e=241,p=0,cr=0,cu=0,mis=0,r=2,dep=0,og=1,tim=51150136462
WAIT #1: nam='SQL*Net message from client' ela= 2143 p1=1650815232 p2=1 p3=0
STAT #1 id=1 cnt=3 pid=0 pos=1 obj=0 op='SORT GROUP BY (cr=6204 pr=6228 pw=0 time=1535323 us)'
STAT #1 id=2 cnt=118 pid=1 pos=1 obj=0 op='HASH JOIN (cr=6204 pr=6228 pw=0 time=1509029 us)'
STAT #1 id=3 cnt=18194 pid=2 pos=1 obj=66386 op='TABLE ACCESS FULL SALES (cr=4657 pr=4655 pw=0 time=1258785 us)'
STAT #1 id=4 cnt=12000 pid=2 pos=2 obj=0 op='MERGE JOIN CARTESIAN (cr=1547 pr=1573 pw=0 time=287550 us)'
STAT #1 id=5 cnt=1 pid=4 pos=1 obj=51510 op='TABLE ACCESS FULL PRODUCT (cr=3 pr=32 pw=0 time=8072 us)'
STAT #1 id=6 cnt=12000 pid=4 pos=2 obj=0 op='BUFFER SORT (cr=1544 pr=1541 pw=0 time=267504 us)'
STAT #1 id=7 cnt=12000 pid=6 pos=1 obj=66384 op='TABLE ACCESS FULL CUSTOMER (cr=1544 pr=1541 pw=0 time=218698 us)'
=====================

Let us study about the STAT lines. These are the lines converted into ROW SOURCE in the tkprof output.
Each STAT line contains the following statistics:
STAT #1 represents the cursor ID
id = Unique ID of the ROW SOURCE operation within the STAT line set
cnt = Number of rows returned by an individual operation
pid = ID of this operations parent operation
pos = Position number.
obj = Object ID
op = Name of the operation ( cr = consistent read, pr = # of Physical Reads, pw = # of Physical Writes,
time = elapsed duration in Microseconds in 9i/10g)
Beacon Infotech Corporation
www.oracleact.com

30

2007-12-25

Oracle Performance Tuning 3. Trace File Walk Through.


456
457
458
459
460
461
462
463

PARSING IN CURSOR #2 len=6 dep=0 uid=45 oct=44 lid=45 tim=51150143465 hv=3480936638 ad='9474c610'
commit
END OF STMT
PARSE #2:c=0,e=422,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=51150143445
XCTEND rlbk=0, rd_only=1
EXEC #2:c=0,e=381,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=51150144326
WAIT #2: nam='SQL*Net message to client' ela= 5 p1=1650815232 p2=1 p3=0
WAIT #2: nam='SQL*Net message from client' ela= 1129 p1=1650815232 p2=1 p3=0

464 =====================

TRANSACTION END MARKS


rlbk = True(1) if the transaction was rolled back
rd_only = True(1) if the transaction changed no data in the database.

The last few lines:


465 PARSING IN CURSOR #1 len=56 dep=0 uid=45 oct=42 lid=45 tim=51150146912 hv=3517064084 ad='947874a0'
466 alter session set events '10046 trace name context off'
467 END OF STMT
468 PARSE #1:c=0,e=185,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=51150146895
469 BINDS #1:
470 EXEC #1:c=0,e=498,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=51150147878

Beacon Infotech Corporation


www.oracleact.com

31

2007-12-25

Oracle Performance Tuning 3. Trace File Walk Through.


Points to remember:
1. Total Response time = ( The last tim value The fist tim value)
= (51,150,147,878 - 51,148,583,752) = 1,564,126 Micro Seconds
= 1.5 Seconds

Tkprof output:
call
count
cpu elapsed disk
query
current
rows
------------ ----------------- ---------- ---------- ---------- ---------Parse
1
0.00
0.00
0
0
0
0
Execute 1
0.01
0.00
0
0
0
0
Fetch
2
1.57
1.53
6228
6204
0
3
------------------- ---------- ---------- ---------- ------------------total
4
1.58
1.53
6228
6204
0
3
===========================================================
2. Unaccounted Time
You will always find some unaccounted time in the trace file because some lag in computing the
elapsed time. Do not expect perfection from the wall clocks.
3. Recursive Calls whose depth > 0
Recursive database calls value of statistics in the set (c, e, p, cr, cu ) is an aggregation of
consumption for the entire recursive family tree.
4. No idle event
All wait events are important to measure response time calculation prior to 10g. In 10g Oracle
categorizes some events as idle events example pmon timer etc.
Beacon Infotech Corporation
www.oracleact.com

32

2007-12-25

Oracle Performance Tuning

4. Tkprof

What is SQL tuning?


There are several definitions available for SQL
Tuning.
My simple one is:
Science of Reducing Logical IO and elapsed time.
Why reducing LIO? The reasons are:
More LIOs mean more latches to be held in the SGA.
More latches mean more CPU service.
More CPU service means less concurrency.
Less concurrency means less scalability.
TKPROF stands for Trace Kernel PROFile. Its a tool
that diagnosis the application code.
Beacon Infotech Corporation
www.oracleact.com

33

2007-12-25

Oracle Performance Tuning

4. Tkprof

Why SQL tune?


There are many reasons to tune poorly written SQL.
Some of them are:
1.

To improve application response time.

2.

To improve batch jobs performance.

3.

To improve scalability of the application.

4.

To stop costly hardware upgrade.

5.

To improve system workload.

Beacon Infotech Corporation


www.oracleact.com

34

2007-12-25

Oracle Performance Tuning

4. Tkprof
where:

What is Cost?

#SRDs is the number of single block


reads

By the definition in the 9.2


Performance Tuning Guide:

#MRDs is the number of multi block


reads

Cost = (
#SRds * sreadtim +

#CPUCycles is the number of CPU


Cycles *)

#MRds * mreadtim +

sreadtim is the single block read


time in Milliseconds

#CPUCycles / cpuspeed
) / sreadtim

mreadtim is the multi block read


time in Milliseconds

This formula is applicable to only nonparallel SQL statement.

cpuspeed is the CPU cycles per


second

Reference:
http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96533/ex_plan.htm#19259
You dont see this formula in 10g Performance Tuning Guide manual. I suspect Oracle Corp does
not want too many questions about the validity of this formula any more.
Beacon Infotech Corporation
www.oracleact.com

35

2007-12-25

Oracle Performance Tuning


A. Choose correct Index

4. Tkprof

Understanding Explain Plan --- I have 3 tables:

SQL> desc customer


Name
Null? Type
-------------------- -------- -------------CUST_ID
NOT NULL NUMBER(38) PK
NAME
NOT NULL VARCHAR2(30)
DOJ
NOT NULL DATE
SOME_TEXT
VARCHAR2(500)
STATE
CHAR(2)

SQL> desc sales

SQL> select count(*) from customer;


COUNT(*)
---------20,000

Name

Null?

Type

-------------------- -------- --------------

SQL> desc product


Name
Null? Type
-------------------- -------- -------------PRODUCT_ID
NOT NULL NUMBER(38) PK
PRODUCT_CAT
NOT NULL VARCHAR2(30)
COUNTRY
CHAR(3)
SALE_PRICE
NUMBER

INV_NUM

NOT NULL NUMBER(38)

CUST_ID

NOT NULL NUMBER(38)

SALE_DATE

DATE

PRODUCT_ID

NOT NULL NUMBER(38)

SALE_QTY

NUMBER(38)

SALE_AMT

NUMBER(12,2)

SOMETXT

VARCHAR2(500)

PK

NO FK constraints are created.

SQL> select count(*) from sales;


COUNT(*)
---------1,000,000

SQL> select count(*) from product ;


COUNT(*)
---------30,005
Beacon Infotech Corporation
www.oracleact.com

36

2007-12-25

Oracle Performance Tuning

4. Tkprof.

Now our requirement is to list all customers who have


bought a TV during the First Quarter of 2004 in
Georgia State.
The SQL is:
select c.Name, p.product_cat, s.sale_date, s.sale_qty, s.sale_amt
from sales s, product p, customer c
where s.cust_id = c.cust_id
and s.product_id = p.product_id
and s.sale_date between to_date('01/01/2004 00:00:00','MM/DD/YYYY HH24:MI:SS')
and to_date('03/31/2004 23:59:59','MM/DD/YYYY HH24:MI:SS')
and c.state = 'GA'
and p.product_cat = 'TV'
order by c.name, p.product_cat, s.sale_date;

First, let us see what explain plan says:


Beacon Infotech Corporation
www.oracleact.com

37

2007-12-25

Oracle Performance Tuning

4. Tkprof.

-------------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT
|
| 16 | 1536 | 10752 (6)| 00:01:21 |
| 1 | SORT ORDER BY
|
| 16 | 1536 | 10752 (6)| 00:01:21 |
| 2 | NESTED LOOPS
|
| 16 | 1536 | 10751 (6)| 00:01:21 |
|* 3 | HASH JOIN
|
| 322 | 22862 | 10588 (6)| 00:01:20 |
|* 4 | TABLE ACCESS FULL
| PRODUCT
| 300 | 5700 | 22 (28)| 00:00:01 |
|* 5 | TABLE ACCESS FULL
| SALES
| 4524 | 229K| 10565 (6)| 00:01:20 |
|* 6 | TABLE ACCESS BY INDEX ROWID | CUSTOMER
| 1 | 25 | 1 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN
| CUSTOMER_PK | 1 |
| 0 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------3 - access("S"."PRODUCT_ID"="P"."PRODUCT_ID")
4 - filter("P"."PRODUCT_CAT"='TV')
5 - filter("S"."SALE_DATE">=TO_DATE('2004-01-01 00:00:00', 'yyyy-mm-dd
hh24:mi:ss') AND "S"."SALE_DATE"<=TO_DATE('2004-03-31 23:59:59', 'yyyy-mm-dd
hh24:mi:ss'))
6 - filter("C"."STATE"='GA')
7 - access("S"."CUST_ID"="C"."CUST_ID")

Beacon Infotech Corporation


www.oracleact.com

38

2007-12-25

Oracle Performance Tuning

4. Tkprof...

TKPROF output shows:


call
count
cpu elapsed disk
query current
rows
------------ ------- ---------- ---------- ---------- ---------- ---------Parse
1
0.02
0.01
0
0
0
0
Execute
1
0.00
0.00
0
0
0
0
Fetch
2
9.35
9.13
77882
78078
0
38
------------ -------- ------------------- ---------- ---------- ---------total
4
9.37
9.15
77882
78078
0
38
Optimizer mode: ALL_ROWS
Rows Row Source Operation
------- --------------------------------------------------38 SORT ORDER BY (cr=78078 pr=77882 pw=0 time=9135276 us)
38 NESTED LOOPS (cr=78078 pr=77882 pw=0 time=15991735 us)
166 HASH JOIN (cr=77744 pr=77681 pw=0 time=8982872 us)
736 TABLE ACCESS FULL PRODUCT (cr=114 pr=113 pw=0 time=26605 us)
4591 TABLE ACCESS FULL SALES (cr=77630 pr=77568 pw=0 time=8821713 us)
38 TABLE ACCESS BY INDEX ROWID CUSTOMER (cr=334 pr=201 pw=0 time=61716 us)
166 INDEX UNIQUE SCAN CUSTOMER_PK (cr=168 pr=41 pw=0 time=15565 us)(object id 67281)

Note: To fetch 38 rows, this SQL consumed 78078 LIO which is very high.
The line TABLE ACCESS FULL SALES (cr=77630 pr=77568 pw=0 time=8821713 us) really
shows the inefficiency of the access plan b/c of a very high consistent and physical reads.
In a OLTP system and in a single table query, I expect 10 to 20 LIO consumption per row
output, if the SQL does not
contain an aggregate function. Look at the elapsed time , 9.15 seconds, very high.
The ration of blocks /row is 2054. So, we need to tune this SQL.
Beacon Infotech Corporation
www.oracleact.com

39

2007-12-25

Oracle Performance Tuning

4. Tkprof.

Now I created an index on SALES table on column SALE_DATE.


The new tkprof output shows:
call
count
cpu elapsed disk
query current
rows
------------ -------- ----------------- ---------- ---------- ---------Parse
1
0.02
0.01
0
0
0
0
Execute
1
0.00
0.00
0
0
0
0
Fetch
2
0.95
0.93
4800
5054
0
38
------------ -------- ---------- ---------- ---------- ---------- ---------total
4
0.97
0.94
4800
5054
0
38
Optimizer mode: ALL_ROWS
Rows Row Source Operation
------- --------------------------------------------------38 SORT ORDER BY (cr=5054 pr=4800 pw=0 time=931004 us)
38 NESTED LOOPS (cr=5054 pr=4800 pw=0 time=1290030 us)
166 HASH JOIN (cr=4720 pr=4599 pw=0 time=359500 us)
736 TABLE ACCESS FULL PRODUCT (cr=114 pr=113 pw=0 time=22107 us)
4591 TABLE ACCESS BY INDEX ROWID SALES (cr=4606 pr=4486 pw=0 time=794955 us)
4591
INDEX RANGE SCAN SALES_SALE_DATE_IDX (cr=15 pr=15 pw=0 time=23580 us)(object id 67290)
38 TABLE ACCESS BY INDEX ROWID CUSTOMER (cr=334 pr=201 pw=0 time=39683 us)
166 INDEX UNIQUE SCAN CUSTOMER_PK (cr=168 pr=41 pw=0 time=12164 us)(object id 67281)
********************************************************************************

Note: We have achieved a dramatic improvemnet both in explased time and LIO
requirement. Some times you may achieve the expected ratio because of the
ways rows inserted and the row length.
The current ratio is 133 which is better than the previous (2054).
Beacon Infotech Corporation
www.oracleact.com

40

2007-12-25

Oracle Performance Tuning

4. Tkprof.

Let us study another example to reduce elapsed time:


B. To Find a MAX Row Within a Group.

SQL> desc mytable


Name

select empid, last_pay_date, net_pay, cum_net,


cum_fed_tax, cum_state_tax
from mytable a
where a.last_pay_date = (select max(last_pay_date)
from mytable b
where b.empid = a.empid)

Type

------------------- -------- -------------EMPID

call
count
cpu elapsed
disk
query
current rows
------------ ----------------- ---------- ------------------- ---------Parse
1
0.02
0.01
0
308
0
0
Execute
1
0.00
0.00
0
0
0
0
Fetch
21
2.70
2.64
524
171433
0
10000
------------------- ---------- ------------------- ---------- ---------total
23
2.72
2.66
524
171741
0
10000
Rows Row Source Operation in 9i
------- --------------------------------------------------10000 FILTER
170000 TABLE ACCESS FULL MYTABLE
165904 SORT AGGREGATE
165904 FIRST ROW
165904 INDEX RANGE SCAN (MIN/MAX) MYTABLE_UK (object id 68368)
Beacon Infotech Corporation
www.oracleact.com

Null?

41

NOT NULL NUMBER(10)

LAST_PAY_DATE

NOT NULL DATE

NET_PAY

NUMBER(10,2)

CUM_GROSS

NUMBER(10,2)

CUM_NET

NUMBER(10,2)

CUM_FED_TAX

NUMBER(10,2)

CUM_STATE_TAX

NUMBER(10,2)

SOMETXT

VARCHAR2(200)

Unique index on EMPID +


LAST_PAY_DATE is created

2007-12-25

Oracle Performance Tuning

4. Tkprof.

To Find a MAX Row Within a Group.


select empid, last_pay_date, net_pay, cum_gross,
cum_net, cum_fed_tax, cum_state_tax
from ( select a.* ,
max(last_pay_date) over(partition by empid) lpdt
from mytable a
)b
where b.lpdt = b.last_pay_date
call
count
-----------Parse
1
Execute
1
Fetch
21
-----------total
23

cpu elapsed
disk
query
-------- ---------- ---------- ---------0.01
0.01
0
356
0.00
0.00
0
0
1.90
1.86
0
170525
------- ------------------- ---------1.91
1.87
0
170881

current
---------0
0
0
---------0

rows
---------0
0
10000
---------10000

Rows Row Source Operation in 9i


------- --------------------------------------------------10000 VIEW
170000 WINDOW BUFFER
170000 TABLE ACCESS BY INDEX ROWID MYTABLE
170000 INDEX FULL SCAN MYTABLE_UK (object id 68368)
Beacon Infotech Corporation
www.oracleact.com

42

I simply rewrote the SQL


statement to use
ANALYTICAL Function.
The elapsed time is
reduced to 1.87 Seconds
from 2.66.
A performance
improvement of 30 %.

2007-12-25

Oracle Performance Tuning

4. Tkprof.

C. Reduce function call

My query is:

create or replace function t1_fn


( p1 IN number, p2 in number, p3 in number )
return number IS
PRAGMA AUTONOMOUS_TRANSACTION;
begin
insert into temp_t1 values (1);
commit;
return (p1*p2)+p3 ;
end;
/

select t1.a, t1.b,


t2.c, t2.d,
max(t1_fn(t1.a, t1.b, t1.c)) max1,
max(t1_fn(t1.c, t1.a, t1.b)) max2
from t1, t2
where t1.a = t2.a and
t1.b = t2.b and
t1.d = t2.d
group by t1.a, t1.b, t2.c, t2.d ;

SQL> desc t1
Name
Null? Type
----------------- -------- -----------A
NUMBER
B
NUMBER
C
NUMBER
D
NUMBER
RDT
DATE
Number of ROWS = 100

Beacon Infotech Corporation


www.oracleact.com

SQL> desc t2
Name
Null? Type
----------------- -------- -----------A
NUMBER
B
NUMBER
C
CHAR(1)
D
NUMBER
Number of ROWS = 100
43

2007-12-25

Oracle Performance Tuning


SQL> @t1_q1
A
-----10

B
C
-------- 20 x

Now the new query is:


D
------40

MAX1 MAX2
-------- -------230
320

SQL> select count(*) from temp_t1 ;


COUNT(*)
---------20000

Why is the function called 20,000


times when each table has only 100
rows?

Beacon Infotech Corporation


www.oracleact.com

4. Tkprof.
select t1.a, t1.b, t2.c, t2.d,
max(x1) max1, max(x2) max2
from (select a, b,d , t1_fn(a,b,c) x1 ,
t1_fn(c,a,b) x2 ,
rownum rn
from t1) t1, t2
where t1.a = t2.a and
t1.b = t2.b and
t1.d = t2.d
group by t1.a, t1.b, t2.c, t2.d ;
Now compare function call.
SQL> select count(*) from temp_t1 ;
COUNT(*)
---------200

44

2007-12-25

Oracle Performance Tuning

4. Tkprof.

!!!! From 20000 calls to 200 calls. !!!


The trick is adding ROWNUM in an in-line view. Oracle will
materialize the view before joining with another table.
Another method is using a hint - NO_MERGE.
By reducing function calls, you are not only improving
response time but also increasing scalability of the
application.

Beacon Infotech Corporation


www.oracleact.com

45

2007-12-25

Oracle Performance Tuning

4. Tkprof.

Importance of ROW SOURCE information in SQL tuning


What you should look for:
1.

Driving table Choose the one that returns fewer rows

2.

Access paths Via Index, Full table scan, Hash/Index


Cluster

3.

Number of rows returned from each operation

4.

Join Methods NL, HASH, Sort Merge, Window Sort,


Window Buffer

5.

Check whether you can reduce the # of rows in each


operation

6.

# of LIO consumed per row Max of 20 per table is


acceptable, 100 in a 5-tables Query.

7.

Use Analytical function if possible.

8.

Look carefully WAIT Events

Beacon Infotech Corporation


www.oracleact.com

46

2007-12-25

Oracle Performance Tuning


I value your questions, comments and suggestions.
Please send your comment to tamil_s_g@oracleact.com
Beacon Infotech Corporation.
Web: www.oracleact.com

Beacon Infotech Corporation


www.oracleact.com

47

2007-12-25