of 65
8/13/2019 Rac Performance Tuning
1/65
1 juliandyke.com2008 Julian Dyke
RAC Performance Tuning
Web Version - May 2008
Julian Dyke
Independent Consultant
8/13/2019 Rac Performance Tuning
2/65
2008 Julian Dyke juliandyke.com2
Agenda
RAC Performance Tuning
Tools
Cluster Design
Workload Management
Optimizing Execution Plans Reducing Redo
Reducing Contention
Optimizing the Library Cache
Data Design Application Design
Partitioning
8/13/2019 Rac Performance Tuning
3/65
2008 Julian Dyke juliandyke.com3
Tools
8/13/2019 Rac Performance Tuning
4/65
2008 Julian Dyke juliandyke.com4
ToolsAWR AWR is the best tuning resource:
Requires Enterprise Manager Diagnostics Pack Can only be used with Enterprise Edition
EM Diagnostics Pack licence covers:
AWR ASH
ADDM
Enterprise Manager Performance Pages
EM Diagnostics Pack therefore includes
V$ACTIVE_SESSION_HISTORY
DBA_HIST_%views
DBMS_WORKLOAD_REPOSITORYpackage
8/13/2019 Rac Performance Tuning
5/65
2008 Julian Dyke juliandyke.com5
ToolsAWR Default snapshot interval is 60 minutes
Good for trend analysis Probably too long for problem investigation
Default retention period is 7 days
Reduces space consumption (SYSAUXtablespace) Probably too short for problem investigation
Can optionally create baselines
Difference between two snapshots
Reports can be generated in HTML or text format using
Enterprise Manager
SQL*Plus scripts
8/13/2019 Rac Performance Tuning
6/65
2008 Julian Dyke juliandyke.com6
ToolsASH Require EM Diagnostics pack
Based on sampling
Useful data stored in
V$ACTIVE_SESSION_HISTORY(recent) DBA_HIST_ACTIVE_SESS_HISTORY (historic)
Reports can be generated in HTML or text format using
Enterprise Manager
SQL*Plus scripts
Additional data can be obtained by drilling down intoDBA_HIST_ACTIVE_SESS_HISTORY
8/13/2019 Rac Performance Tuning
7/652008 Julian Dyke juliandyke.com7
ToolsSTATSPACK If AWR is not available use STATSPACK
Only Oracle tool that can be used:with Standard Edition
if you have not purchased EM Diagnostics Pack
Package and repository must be manually installed andconfigured
Repository must be manually managed and purged
Snapshots cannot be co-ordinated across RAC instances
Not integrated into kernel
Snapshots can skew result data
Includes
time model statistics (by default)
segment statistics (optional)
8/13/2019 Rac Performance Tuning
8/652008 Julian Dyke juliandyke.com8
ToolsDBMS_XPLAN Introduced in Oracle 9.2
Displays execution plans in EXPLAINplan table
Enhanced in Oracle 10.1 and above
Additionally displays execution plans for:
last statement executed by sessionchild cursor in library cache
child cursors stored in AWR
Library cache
Execution plan only exists until statement is aged out
AWR
Not all cursors are stored in AWR
8/13/2019 Rac Performance Tuning
9/652008 Julian Dyke juliandyke.com9
ToolsTrace For in-depth analysis it may be necessary to enable SQL trace
In Oracle 10.1 and above use DBMS_MONITORpackage
Enables 10046 level 8 (wait events) by default
Allows trace to be enabled
For sessionsFor specific client identifiers
For service / module / action
For older versions use login triggers
TKPROFnow includes wait events
Useful when talking to developers
8/13/2019 Rac Performance Tuning
10/652008 Julian Dyke juliandyke.com10
ClusterDesign
8/13/2019 Rac Performance Tuning
11/652008 Julian Dyke juliandyke.com11
Cluster DesignMultiple Databases Oracle Clusterware is relatively scalable
RAC databases are less scalable
If cluster contains multiple databases
Minimize number of instances for each database
Minimizes interconnect trafficMaximizes buffer cache efficiency
Configure instances for each database on all nodes
Maximize operational flexibility
Shutdown and disable unused instances
Dependent on
Application Design
Workload
8/13/2019 Rac Performance Tuning
12/652008 Julian Dyke juliandyke.com12
Cluster DesignNode Affinity Attempt to achieve node affinity for individual data blocks
Minimizes interconnect traffic Maximizes buffer cache efficiency
At segment level use:
Database services Partitioning (range/list/system)
At block level reduce number of rows per block using:
PCTFREEstorage clause
ALTER TABLE MINIMIZE RECORDS_PER_BLOCK
Filler columns e.g.
FILLER CHAR(2000)
Multiple block sizes
8/13/2019 Rac Performance Tuning
13/652008 Julian Dyke juliandyke.com13
Cluster DesignDynamic Resource Mastering Every resource is mastered by an instance
Initially resource masters is distributed across availableinstances
If an individual node uses a specific resource frequently
Resource can be remastered to local node
In Oracle 9.2
Appears in documentation
Not implemented
In Oracle 10.1
Implemented at data file level
Relatively high thresholds In Oracle 10.2
Implemented at segment level
Relatively low thresholds
8/13/2019 Rac Performance Tuning
14/652008 Julian Dyke juliandyke.com14
WorkloadManagement
8/13/2019 Rac Performance Tuning
15/652008 Julian Dyke juliandyke.com15
Workload ManagementBatch Processing Migrations and one-offs
Can often run faster on a single-node Shutdown remaining nodes in cluster
Batch processing - single node
Use database services to achieve node affinitySpecify preferred and available node
Better than hard-coding instance names
Batch processing - multiple nodes
Use parallel execution
Parallel statements can execute concurrently onmultiple instances
Configure using hints - not at object level
8/13/2019 Rac Performance Tuning
16/65
2008 Julian Dyke juliandyke.com16
Optimizing
Execution
Plans
O ti i i E ti Pl
8/13/2019 Rac Performance Tuning
17/65
2008 Julian Dyke juliandyke.com17
Optimizing Execution PlansOverview Causes of bad execution plans
Missing indexes Inadequate optimizer statistics
usually inaccurate selectivity predictions
Often characterized by excessive amounts of logical I/O
high elapsed times for statements
gc cr multi block request waits
gc buffer busy waits
db file sequential / scattered read waits
O ti i i E ti Pl
8/13/2019 Rac Performance Tuning
18/65
2008 Julian Dyke juliandyke.com18
Optimizing Execution PlansMissing Indexes In Oracle 10.1 and above, DBMS_ADVISOR can be used to
identify missing indexes
DBMS_ADVISORcan be used with
a representative workload
a single statement
DBMS_ADVISORcan recommend
indexes
materialized views
Requires Enterprise Manager Tuning Pack licence
Prerequisite is Enterprise Manager Diagnostics Pack
O ti i i E ti Pl
8/13/2019 Rac Performance Tuning
19/65
2008 Julian Dyke juliandyke.com19
Optimizing Execution PlansMissing Indexes To use the quick tune feature of the DBMS_ADVISOR, first
create a directory for the results:
CREATE OR REPLACE DIRECTORY advisorAS '/u01/app/oracle/advisor';
GRANT READ,WRITE ON DIRECTORY advisor TO PUBLIC;
Execute the advisor against the target SQL statement:EXECUTE dbms_advisor.quick_tune ( - DBMS_ADVISOR.SQLACCESS_ADVISOR, -
task_name => 'TASK1', -attr1 => 'SELECT c2 FROM t1 WHERE c1 = :b1');
Generate the advice scriptEXECUTE dbms_advisor.create_file ( -
buffer => dbms_advisor.get_task_script (task_name => 'TASK1'),location => 'ADVISOR', -filename => 'task1.sql');
O ti i i E ti Pl
8/13/2019 Rac Performance Tuning
20/65
2008 Julian Dyke juliandyke.com20
Optimizing Execution PlansMissing Indexes The advice script contains DDL statements to create the
missing indexes For example:
Rem SQL Access Advisor: Version 10.2.0.1.0 - ProductionRemRem Username: US01
Rem Task: TASK1Rem Execution date: 07/01/2007 23:07Rem
CREATE INDEX "US01"."T1_IDX$$_15180001"ON "US01"."T1"("C1")
COMPUTE STATISTICS;
O ti i E ti Pl
8/13/2019 Rac Performance Tuning
21/65
2008 Julian Dyke juliandyke.com21
Optimizer Execution PlansBind Variable Capture In Oracle 10.1 and above, bind variable values for individual
statements are periodically written to V$SQL_BIND_CAPTURE also known as O$SQL_BIND_CAPTURE
Useful when trying to tune a bad execution plan
Use bind variable values in SQL*Plus script
Beware of implicit conversions especially for DATEtypes
SELECT child_number,position,name,datatype_string,value_stringFROM v$sql_bind_captureWHERE sql_id = '62crfkp6htg8p'ORDER BY 1,2;
Child Number Position Name Data Type Value
0 1 :B1 NUMBER 1719249
0 2 :B2 NUMBER 1719249
0 3 :B3 NUMBER 488304
0 4 :B4 NUMBER 110
O ti i i E ti Pl
8/13/2019 Rac Performance Tuning
22/65
2008 Julian Dyke juliandyke.com22
Optimizing Execution PlansSystem Statistics If your RAC cluster has symmetrical hardware then consider
using system statistics
System statistics are gathered using:
EXECUTE DBMS_STATS.GATHER_SYSTEM_STATS;
By default statistics are stored in SYS.AUX_STATS$
If available system statistics are used by the Cost-BasedOptimizer to produce better execution plans
System statistics are database-specific
Do not use in RAC environments with asymmetrichardware
O ti i i E ti Pl
8/13/2019 Rac Performance Tuning
23/65
2008 Julian Dyke juliandyke.com23
Optimizing Execution PlansStatistics Collection Avoid unnecessary object statistics collection
Objects are invalidated by defaultExecution plans must be regenerated
Use DBMS_STATSNO_INVALIDATEflag
Consider setting statistics using DBMS_STATSpackage
Useful with partitions Consider
Stored Outlines
SQL Profiles
Better solutions exist in Oracle 11.1
e.g multi column histograms
8/13/2019 Rac Performance Tuning
24/65
2008 Julian Dyke juliandyke.com24
ReducingRedo
Reducing Redo
8/13/2019 Rac Performance Tuning
25/65
2008 Julian Dyke juliandyke.com25
Reducing RedoEliminate Unused Indexes In Oracle 9.0.1 and above, index monitoring can be used to
determine which indexes are currently in use To enable index monitoring on index1 use
ALTER INDEX index1 MONITORING USAGE;
To check which indexes are currently being monitored use:
SELECT index_name,monitoringFROM v$object_usage;
To check which indexes have been used by the optimizer use:
SELECT index_name, used
FROM v$object_usage;
To disable index monitoring on index1 use:
ALTER INDEX index1 NOMONITORING USAGE;
Reducing Redo
8/13/2019 Rac Performance Tuning
26/65
2008 Julian Dyke juliandyke.com26
Reducing RedoUnnecessary Column Updates For example:
SELECT a,b,c,d,e,f,g,h,i,jINTO l_a,l_b,l_c,l_d,l_e,l_f,l_g,l_h,l_i,l_jFROM t1WHERE z = :b1FOR UPDATE;
l_a = l_a + 1;
UPDATE t1SET
a = :l_a;b = :l_b;c = :l_c;d = :l_d;
e = :l_e;f = :l_f;g = :l_g;h = :l_h;i = :l_i;
j = :l_jWHERE z = :b1;
Reducing Redo
8/13/2019 Rac Performance Tuning
27/65
2008 Julian Dyke juliandyke.com27
Reducing RedoUnnecessary Column Updates When a column is updated with an unchanged value:
Undo is generated for the old valueWritten back to undo block
Written to online redo log
Redo is generated for the new value
Written to online redo log Both values will subsequently be:
Copied to archived redo log
Transported to standby database (if configured)
Code on previous slide might be rewritten as:
UPDATE t1SET a = a + 1WHERE z = :b1;
Reducing Redo
8/13/2019 Rac Performance Tuning
28/65
2008 Julian Dyke juliandyke.com28
Reducing RedoAvoid Unnecessary Commits Avoid unnecessary commits
For example:
LOOP...INSERT INTO t1 VALUES (lx,ly,lz);COMMIT;...
END LOOP;
LOOP...INSERT INTO t1 VALUES (lx,ly,lz);...
END LOOP;COMMIT;
The COMMIT can often be moved outside the loop
For example:
8/13/2019 Rac Performance Tuning
29/65
2008 Julian Dyke juliandyke.com29
ReducingContention
Reducing Contention
8/13/2019 Rac Performance Tuning
30/65
2008 Julian Dyke juliandyke.com30
Reducing ContentionRow Level Locking Avoid pessimistic locking using SELECT FOR UPDATE
Setting row lock generates additional undo/redo Requires rollback if transaction uncommitted
SELECT FOR UPDATEchanges cannot be batched
Individual undo / redo generated for each row
If possible lock data when it is updated
May require additional error handling
Reducing Contention
8/13/2019 Rac Performance Tuning
31/65
2008 Julian Dyke juliandyke.com31
Reducing ContentionAvoid Pessimistic Locking Pessimistic locking is usually implemented using SELECT
FOR UPDATEstatements For example:
CURSOR c1 IS SELECT x,y FROM t1;
LOOPFETCH FROM c1 INTO lx, ly;
SELECT y,z FOR UPDATE FROM t2 WHERE x = lx;UPDATE t2 SET y = ly WHERE x = lx;....
END LOOP;
CURSOR c1 IS SELECT x,y FROM t1;
LOOPFETCH FROM c1 INTO lx, ly;UPDATE t2 SET y = ly WHERE x = lx;....
END LOOP;
Might be rewritten without the SELECT FOR UPDATEstatement
Reducing Contention
8/13/2019 Rac Performance Tuning
32/65
2008 Julian Dyke juliandyke.com32
Reducing ContentionSequences Use sequences instead of tables to generate sequential
numbers For example if the existing code is:
SELECT MAX (c1) INTO :b1 FROM t1;UPDATE t1 SET c1 = c1 + 1;
INSERT INTO t2 VALUES (:b1,....);
Create a sequence
CREATE SEQUENCE s1;
INSERT INTO t2 (s1.NEXTVAL,....);
The code can then be rewritten as:
Reducing Contention
8/13/2019 Rac Performance Tuning
33/65
2008 Julian Dyke juliandyke.com33
Reducing ContentionSequences
By default sequences have a cache size of 20
CREATE SEQUENCE s1;
Each instance will allocate a batch of 20 sequence numbersthe first time the sequence is accessed after instance startup
Allocating a new batch of sequence numbers requires the SQ
enqueue In databases with high insertion rates, it may be necessary to
increase the sequence cache size to reduce contention for theSQ enqueue
For example:
CREATE SEQUENCE s1 CACHE 1000;
Reducing Contention
8/13/2019 Rac Performance Tuning
34/65
2008 Julian Dyke juliandyke.com34
Reducing ContentionSequences Cached sequence numbers
Will not necessarily be issued consecutively acrossinstances
Can include gaps caused by
Rollbacks
Aging out of dictionary cache sequence objects
Instance restarts
Instance failover / switchover
Flushing cache
Reducing Contention
8/13/2019 Rac Performance Tuning
35/65
2008 Julian Dyke juliandyke.com35
Reducing ContentionSequences Ordered Sequence Numbers
If sequence requires ORDERclauseRAC instances must use SV enqueue to coordinate
sequence numbers
Increases contention
Monotonically increasing sequence numbers may causedcontention for right hand index leaf blocks
For RAC instances
Set large cache size (e.g. 50000)
8/13/2019 Rac Performance Tuning
36/65
Reducing Contention
8/13/2019 Rac Performance Tuning
37/65
2008 Julian Dyke juliandyke.com37
Reducing ContentionReverse Key Indexes Introduced in Oracle 8.0
Designed to reduce contention for index insertions
Column order is preserved
Contents of each column are reversed
Useful in RAC to reduce inter-instance contention
However, no node affinity unless leading column(s) are
node specific
Only useful where rows are accessed using equalitypredicates
Reducing Contention
8/13/2019 Rac Performance Tuning
38/65
2008 Julian Dyke juliandyke.com38
Reducing ContentionReverse Key Indexes Consider the following
CREATE TABLE t1 (firstname VARCHAR2(30), surname VARCHAR2(30);
INSERT INTO t1 VALUES ('Fernando','Alonso');INSERT INTO t1 VALUES ('Felipe','Massa');INSERT INTO t1 VALUES ('Kimi','Raikkonen');INSERT INTO t1 VALUES ('Lewis','Hamilton');INSERT INTO t1 VALUES ('Mark','Webber');
CREATE INDEX i1 ON t1 (firstname,surname) REVERSE;
FIRSTNAME SURNAME
epileF assaMimiK nenokkiaR
kraM rebbeW
odnanreF osnolA
siweL notilmaH
The names are stored in the index as below:
8/13/2019 Rac Performance Tuning
39/65
2008 Julian Dyke juliandyke.com39
Optimizing the
Library
Cache
Optimizing the Library Cache
8/13/2019 Rac Performance Tuning
40/65
2008 Julian Dyke juliandyke.com40
Optimizing the Library CacheOverview Use bind variables
Ensure statements are textually identical Including comments and bind variable names
Beware of introducing bind variable peeking issues
If literal values hard coded
Consider using cursor sharing FORCEor SIMILAR
SIMILARcan still generate large numbers of child cursors
Minimize occurrences of multiple child cursors caused by:
Differences in optimizer environment parameterse.g. enabling trace
Differences in bind variable type / length
Differences in NLS settings for sorts / NUMBER
Optimizing the Library Cache
8/13/2019 Rac Performance Tuning
41/65
2008 Julian Dyke juliandyke.com41
Optimizing the Library CacheHard Parsing In a RAC environment hard parsing is particularly expensive
Global locks must be obtained for all tables referenced in thestatement before it can be optimized
Ensure library cache is large enough to avoid cursors ageing
out before they are reused
Use bind variables
Avoid invalidating cursors
Use cursor sharing if necessary
Optimizing the Library Cache
8/13/2019 Rac Performance Tuning
42/65
2008 Julian Dyke juliandyke.com42
Optimizing the Library CacheBind Variables Statements using literals should be rewritten to use bind
variables:INSERT INTO t1 VALUES (1,100);INSERT INTO t1 VALUES (2,200);INSERT INTO t1 VALUES (3,300);
can be rewritten as:
lx := 1; ly := 100;INSERT INTO t1 VALUES (:lx, :ly);
lx := 2; ly := 200;INSERT INTO t1 VALUES (:lx, :ly);
lx := 3; ly := 300;INSERT INTO t1 VALUES (:lx, :ly);
Optimizing the Library Cache
8/13/2019 Rac Performance Tuning
43/65
2008 Julian Dyke juliandyke.com43
Optimizing the Library CacheSoft Parsing Soft parsing occurs
when parent cursor is already in the library cache the first time a session accesses the parent cursor
Need to check existing cursor is valid for new session
parameters
object
access privileges (security)
Soft parsing can be reduced
Not closing cursors in application Using Session Cursor Cache
Using CURSOR_SPACE_FOR_TIMEparameter
Optimizing the Library Cache
8/13/2019 Rac Performance Tuning
44/65
2008 Julian Dyke juliandyke.com44
Optimizing the Library CacheCURSOR_SHARING parameter For applications which do not use binds consider using
cursor sharing
Introduced in Oracle 8.1.6
Stable in Oracle 8.1.7 and above
Values are
EXACT- Default - no cursor sharing
FORCE- 8.1.6 and above - replace all literal values withpseudo-bind variables
SIMILAR- 9.0.1 and above - replace "safe" literal valueswith pseudo-bind variables
Optimizing the Library Cache
8/13/2019 Rac Performance Tuning
45/65
2008 Julian Dyke juliandyke.com45
Optimizing the Library CacheSESSION_CACHED_CURSORS parameter Session cursor cache allows each session to pin multiple
statements cached in SGA Reduces amount of hard parsing
Use parameter SESSION_CACHED_CURSORSto specifynumber of cached cursors to be pinned
Default value is 20 in Oracle 10.2.0.1
Requires small amount of space in PGA
Pins cursor space in SGA heaps Can result in ORA-04031 if set too high
Optimizing the Library Cache
8/13/2019 Rac Performance Tuning
46/65
2008 Julian Dyke juliandyke.com46
Optimizing the Library CacheCURSOR_SPACE_FOR_TIME parameter Keeps open cursors pinned between executions
Can relieve concurrency pressure
Increases space required to hold cursors
Boolean parameter which defaults to FALSE
Not necessary in Oracle 10.2.0.2 and above
Mutexes have replaced library cache latches and pins forrelevant cursor operations
8/13/2019 Rac Performance Tuning
47/65
2008 Julian Dyke juliandyke.com47
DataDesign
Data Design
8/13/2019 Rac Performance Tuning
48/65
2008 Julian Dyke juliandyke.com48
Data DesignAvoid CHAR columns Avoid CHARcolumns where the column length > 1
Use VARCHAR2columns instead CHARcolumns
require more disk space
take more space in buffer cache
For example, consider the amount of space required to store'FERRARI':
E R R A R IFCHAR(10)
E R R A R IFVARCHAR2(10)
CHARcolumns are space-padded to their maximum length
VARCHAR2columns are not space-padded
10
7
Data Design
8/13/2019 Rac Performance Tuning
49/65
2008 Julian Dyke juliandyke.com49
Data DesignDo not store dates as VARCHAR2 For example if a table contains 100 values for each day over
the past 5 years
Using a DATEcolumn data is evenly distributed:
2002 2003 2004 2005 2006
2002 2003 2004 2005 2006
Using a VARCHAR2column data is bunched:
Affects CBO estimates for range scans
Data Design
8/13/2019 Rac Performance Tuning
50/65
2008 Julian Dyke juliandyke.com50
Data DesignUse NULL values Use NULL to represent unknown values
NULL takes a maximum of one byte in row Trailing NULLs do not take any space in row
NULL values are not indexed
Do not use artificial NULL values such as
Space character (0x20) for VARCHAR2
-1 for NUMBER
01-JAN-1980 for DATE
Artificial NULL values Require more disk space
Require indexing
Skew histograms
Data Design
8/13/2019 Rac Performance Tuning
51/65
2008 Julian Dyke juliandyke.com51
gColumn Values Avoid long constant values such as
ENABLEDand DISABLED TRUEand FALSE
YES and NO
Often found in STATUScolumns
Particularly expensive for very large tables
e.g. > 10 million rows
Consume
space on disk
space in buffer cache
and potentially space in indexes
Use a numeric constant e.g. 1,2 etc
If possible use NULLfor most popular value
Data Design
8/13/2019 Rac Performance Tuning
52/65
2008 Julian Dyke juliandyke.com52
gColumn Values For example consider a table containing 10 million invoices of
which 10,000 are printed each nightCREATE TABLE invoice(
.....print_flag varchar2(1)....
);
CREATE INDEX i_invoice1 ON invoice (print_flag);
IF print_flag = 'Y' THEN-- print invoiceprint_flag := 'N';
END IF;
If PRINT_FLAG takes the values NULL or 'Y'
I_INVOICE1 will only contain 10,000 rows
If PRINT_FLAG can take the values 'N' or 'Y'
I_INVOICE1 will contain 10,000,000 rows
8/13/2019 Rac Performance Tuning
53/65
8/13/2019 Rac Performance Tuning
54/65
2008 Julian Dyke juliandyke.com54
ApplicationDesign
Application Design
8/13/2019 Rac Performance Tuning
55/65
2008 Julian Dyke juliandyke.com55
pp gDML Perform DML on sets of rows
INSERT, UPDATEand DELETEsets rather than individualrows
Avoid procedural code
PL/SQL, PRO*C, JDBC etc
Use bulk operations for DML
Set array size
Use PL/SQL FORALLand BULKstatements
Consider using analytic queries Reduce number of block visits per query
Application Design
8/13/2019 Rac Performance Tuning
56/65
2008 Julian Dyke juliandyke.com56
pp gAvoid Procedural Code - INSERT Avoid code which processes individual rows
For example:CURSOR c1 IS SELECT x,y,z FROM t1;
LOOPFETCH FROM c1 INTO lx, ly, lz;....INSERT INTO t2 (x,y,z) VALUES (lx, ly, lz);....
END LOOP;
Might be rewritten as:
INSERT INTO t2 (x,y,z) SELECT x,y,z FROM t1;
Application Design
8/13/2019 Rac Performance Tuning
57/65
2008 Julian Dyke juliandyke.com57
pp gAvoid Procedural Code - UPDATE From the previous example
CURSOR c1 IS SELECT x,y FROM t1;
LOOPFETCH FROM c1 INTO lx, ly;UPDATE t2 SET y = ly WHERE x = lx;....
END LOOP;
Might be rewritten as:
UPDATE t2SET t2.y =(
SELECT t1.yFROM t1WHERE t1.x = t2.x
);
Application Design
8/13/2019 Rac Performance Tuning
58/65
2008 Julian Dyke juliandyke.com58
pp gAvoid DDL Statements Avoid unnecessary DDL Statements
Avoid dynamic schema changes
Temporary tables are often created and dropped during reportgeneration
For example:
LOOP...CREATE TABLE t1 (...);...DROP TABLE t1;...
END LOOP;
Use global temporary tables or TRUNCATEstatement
Application Design
8/13/2019 Rac Performance Tuning
59/65
2008 Julian Dyke juliandyke.com59
pp gRead Consistency Avoid reading recently updated blocks on other instances
Use Database services to ensure node affinity Minimize transaction lengths
Maximize COMMITfrequency
Minimize undo generation
Drop unused indexes
Compress data columns
e.g. use Dor Einstead of DISABLEDor ENABLED
Use nullable columns
Use nullable indexes e.g. NULL / Y
Avoid updating columns where data has not changedBefore and after values are saved even for
unchanged data
Application Design
8/13/2019 Rac Performance Tuning
60/65
2008 Julian Dyke juliandyke.com60
pp gInter-Instance Messages Minimize use of DROPand TRUNCATE
Require inter-instance synchronization to invalidate blockranges in buffer caches
DELETEmay be more efficient for small tables
Use Global Temporary Tables where possible
Avoid using parallel query in OLTP workloads
Parallel queries read blocks directly into local buffers
Require inter-instance synchronization to ensure dirtyblocks in remote buffer caches are flushed back to disk
Optimizer may not consider synchronization costs whenselecting a parallel execution plan
Application Design
8/13/2019 Rac Performance Tuning
61/65
2008 Julian Dyke juliandyke.com61
pp gArray Fetch Use array operations for SELECTstatements
Reduces number of network packets required to FETCHdata
SET ARRAYSIZE 50
In JDBC array size defaults to 10
To set the array size for a connection to 20 rows use:
((OracleStatement)statement).setRowPrefetch (50);
To set the array size for an individual statement to 50 rowsuse:
((OracleConnection)conn).setDefaultRowPrefetch (20);
In SQL*Plus array size defaults to 15
To set the array size to 50 use
Application Design
8/13/2019 Rac Performance Tuning
62/65
2008 Julian Dyke juliandyke.com62
pp gBatch Updates Use batch updates for DML statements (INSERT, UPDATE, and
DELETE) In JDBC, default batch size is 1 row
To set the batch size for a connection to 20 rows use:
((OracleConnection)conn).setDefaultExecuteBatch (20);
To set the batch size for an individual statement to 50 rowsuse:
((OraclePreparedStatement)statement).setExecuteBatch (20);
To send a batch of rows at any time use:
((OraclePreparedStatement)statement).sendBatch ();
Application Design
8/13/2019 Rac Performance Tuning
63/65
2008 Julian Dyke juliandyke.com63
gPL/SQL Bulk Collect
DECLARE -- 100000 row tablel_c3 NUMBER;
CURSOR c1 IS SELECT c3 FROM t1;BEGINOPEN c1;LOOP
FETCH c1 INTO l_c3; -- 3.052 secondsEXIT WHEN c1%NOTFOUND;
END LOOP;CLOSE c1;
END;
DECLARE -- 100000 row tableTYPE NUMTYPE IS TABLE OF NUMBER(6) INDEX BY BINARY_INTEGER;l_c3 NUMTYPE;CURSOR c1 IS SELECT c3 FROM t1;
BEGIN
OPEN c1;LOOPFETCH c1 BULK COLLECT INTO l_c3; -- 0.119 secondsEXIT WHEN c1%NOTFOUND;
END LOOP;CLOSE c1;
END;
Application Design
8/13/2019 Rac Performance Tuning
64/65
2008 Julian Dyke juliandyke.com64
PL/SQL FORALL
DECLARETYPE NUMTYPE IS TABLE OF NUMBER(6) INDEX BY BINARY_INTEGER;
TYPE NAMETYPE IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;l_c1 NUMTYPE;l_c2 NAMETYPE;l_c3 NUMTYPE;
BEGIN
FOR i IN 1..100000 LOOPl_c1(i) := i;l_c2(i) := LPAD (TO_CHAR (i),30,0);l_c3(i) := MOD (i, 100);
END LOOP;
FOR i IN 1..100000 LOOP -- FOR Loop28 seconds
INSERT INTO t1 VALUES (l_c1 (i), l_c2 (i), l_c3(i));END LOOP;
FORALL f IN 1..100000 LOOP -- FORALL Loop4 secondsINSERT INTO t1 VALUES (l_c1 (i), l_c2 (i), l_c3(i));
END;
8/13/2019 Rac Performance Tuning
65/65
Summary Issues almost invariably indicated in Top Five timed events in
AWR / STATSPACK reports Further investigation usually required to pinpoint problem
When you know what the problem is you can almost alwaysfind it in AWR / STATSPACK reports
Not always obvious without prior knowledge
AWR / STATSPACK not very good with statements usingliteral values