Académique Documents
Professionnel Documents
Culture Documents
juliandyke.com
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
juliandyke.com
Tools
juliandyke.com
Tools AWR
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_REPOSITORY package
juliandyke.com
Tools AWR
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 (SYSAUX tablespace) 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
juliandyke.com
Tools ASH
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 into DBA_HIST_ACTIVE_SESS_HISTORY
juliandyke.com
Tools STATSPACK
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 and configured 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)
juliandyke.com
Tools DBMS_XPLAN
Introduced in Oracle 9.2 Displays execution plans in EXPLAIN plan table Enhanced in Oracle 10.1 and above Additionally displays execution plans for: last statement executed by session child 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
juliandyke.com
Tools Trace
For in-depth analysis it may be necessary to enable SQL trace In Oracle 10.1 and above use DBMS_MONITOR package Enables 10046 level 8 (wait events) by default Allows trace to be enabled For sessions For specific client identifiers For service / module / action For older versions use login triggers TKPROF now includes wait events Useful when talking to developers
juliandyke.com
Cluster Design
juliandyke.com
10
Oracle Clusterware is relatively scalable RAC databases are less scalable If cluster contains multiple databases Minimize number of instances for each database Minimizes interconnect traffic Maximizes buffer cache efficiency Configure instances for each database on all nodes Maximize operational flexibility Shutdown and disable unused instances Dependent on Application Design Workload
11
juliandyke.com
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: PCTFREE storage clause ALTER TABLE MINIMIZE RECORDS_PER_BLOCK Filler columns e.g. FILLER CHAR(2000) Multiple block sizes
12
juliandyke.com
Every resource is mastered by an instance Initially resource masters is distributed across available instances 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
13
juliandyke.com
Workload Management
14
juliandyke.com
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 affinity Specify preferred and available node Better than hard-coding instance names Batch processing - multiple nodes Use parallel execution Parallel statements can execute concurrently on multiple instances Configure using hints - not at object level
15
juliandyke.com
juliandyke.com
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
17
juliandyke.com
In Oracle 10.1 and above, DBMS_ADVISOR can be used to identify missing indexes DBMS_ADVISOR can be used with a representative workload a single statement DBMS_ADVISOR can recommend indexes materialized views Requires Enterprise Manager Tuning Pack licence Prerequisite is Enterprise Manager Diagnostics Pack
18
juliandyke.com
To use the quick tune feature of the DBMS_ADVISOR, first create a directory for the results:
CREATE OR REPLACE DIRECTORY advisor AS '/u01/app/oracle/advisor';
GRANT READ,WRITE ON DIRECTORY advisor TO PUBLIC;
19
juliandyke.com
The advice script contains DDL statements to create the missing indexes For example:
Rem Rem Rem Rem Rem Rem SQL Access Advisor: Version 10.2.0.1.0 - Production Username: US01 Task: TASK1 Execution date: 07/01/2007 23:07
20
juliandyke.com
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 DATE types
SELECT child_number,position,name,datatype_string,value_string FROM v$sql_bind_capture WHERE sql_id = '62crfkp6htg8p' ORDER BY 1,2; Child Number 0 0 0 0 Position 1 2 3 4 Name :B1 :B2 :B3 :B4 Data Type NUMBER NUMBER NUMBER NUMBER Value 1719249 1719249 488304 110
21
juliandyke.com
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-Based Optimizer to produce better execution plans System statistics are database-specific Do not use in RAC environments with asymmetric hardware
22
juliandyke.com
Avoid unnecessary object statistics collection Objects are invalidated by default Execution plans must be regenerated Use DBMS_STATS NO_INVALIDATE flag Consider setting statistics using DBMS_STATS package Useful with partitions Consider Stored Outlines SQL Profiles Better solutions exist in Oracle 11.1 e.g multi column histograms
23
juliandyke.com
Reducing Redo
juliandyke.com
24
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;
25
juliandyke.com
For example:
SELECT a,b,c,d,e,f,g,h,i,j INTO l_a,l_b,l_c,l_d,l_e,l_f,l_g,l_h,l_i,l_j FROM t1 WHERE z = :b1 FOR UPDATE;
l_a = l_a + 1; UPDATE t1 SET 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_j WHERE z = :b1;
26
juliandyke.com
When a column is updated with an unchanged value: Undo is generated for the old value Written 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 t1 SET a = a + 1 WHERE z = :b1;
27
juliandyke.com
The COMMIT can often be moved outside the loop For example:
LOOP ... INSERT INTO t1 VALUES (lx,ly,lz); ... END LOOP; COMMIT;
28
juliandyke.com
Reducing Contention
juliandyke.com
29
Avoid pessimistic locking using SELECT FOR UPDATE Setting row lock generates additional undo/redo Requires rollback if transaction uncommitted SELECT FOR UPDATE changes cannot be batched Individual undo / redo generated for each row If possible lock data when it is updated May require additional error handling
30
juliandyke.com
Pessimistic locking is usually implemented using SELECT FOR UPDATE statements For example:
CURSOR c1 IS SELECT x,y FROM t1; LOOP FETCH 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;
31
juliandyke.com
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;
32
juliandyke.com
Each instance will allocate a batch of 20 sequence numbers the 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 the SQ enqueue For example:
CREATE SEQUENCE s1 CACHE 1000;
33
juliandyke.com
Cached sequence numbers Will not necessarily be issued consecutively across instances
Can include gaps caused by Rollbacks Aging out of dictionary cache sequence objects Instance restarts Instance failover / switchover Flushing cache
34
juliandyke.com
Ordered Sequence Numbers If sequence requires ORDER clause RAC instances must use SV enqueue to coordinate sequence numbers Increases contention Monotonically increasing sequence numbers may caused contention for right hand index leaf blocks For RAC instances Set large cache size (e.g. 50000)
35
juliandyke.com
Introduced in Oracle 9.0.1 Works in Oracle 9.2 with some exceptions Stable in Oracle 10.1 Default in Oracle 10.2 Uses bitmaps to manage segment space allocation Recommended for RAC databases Each instance uses a separate bitmap block Eliminates contention for freelists on extent header
36
juliandyke.com
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 equality predicates
37
juliandyke.com
imiK
kraM odnanreF
nenokkiaR
rebbeW osnolA
siweL
38
notilmaH
juliandyke.com
juliandyke.com
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 FORCE or SIMILAR SIMILAR can still generate large numbers of child cursors Minimize occurrences of multiple child cursors caused by: Differences in optimizer environment parameters e.g. enabling trace Differences in bind variable type / length Differences in NLS settings for sorts / NUMBER
40
juliandyke.com
In a RAC environment hard parsing is particularly expensive Global locks must be obtained for all tables referenced in the statement 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
41
juliandyke.com
42
juliandyke.com
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_TIME parameter
43
juliandyke.com
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 with pseudo-bind variables SIMILAR - 9.0.1 and above - replace "safe" literal values with pseudo-bind variables
44
juliandyke.com
Session cursor cache allows each session to pin multiple statements cached in SGA Reduces amount of hard parsing Use parameter SESSION_CACHED_CURSORS to specify number 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
45
juliandyke.com
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 for relevant cursor operations
46
juliandyke.com
Data Design
juliandyke.com
47
Avoid CHAR columns where the column length > 1 Use VARCHAR2 columns instead CHAR columns require more disk space take more space in buffer cache For example, consider the amount of space required to store 'FERRARI': CHAR(10) VARCHAR2(10) 10 7 F F E E R R R R A A R R I I
CHAR columns are space-padded to their maximum length VARCHAR2 columns are not space-padded
48
juliandyke.com
For example if a table contains 100 values for each day over the past 5 years Using a DATE column data is evenly distributed:
2002
2003
2004
2005
2006
2002
2003
2004
2005
2006
49
juliandyke.com
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
50
juliandyke.com
Avoid long constant values such as ENABLED and DISABLED TRUE and FALSE YES and NO Often found in STATUS columns 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 NULL for most popular value
51
juliandyke.com
For example consider a table containing 10 million invoices of which 10,000 are printed each night
CREATE TABLE invoice ( ..... print_flag varchar2(1) .... ); CREATE INDEX i_invoice1 ON invoice (print_flag); IF print_flag = 'Y' THEN -- print invoice print_flag := 'N'; END IF;
If PRINT_FLAG can take the values 'N' or 'Y' I_INVOICE1 will contain 10,000,000 rows If PRINT_FLAG takes the values NULL or 'Y' I_INVOICE1 will only contain 10,000 rows
52
juliandyke.com
Avoid using LONG columns if they will be frequently updated Avoid using VARRAY columns if elements will be Selected individually Updated individually In general avoid both LONG and VARRAY columns if they will exceed one data block Beware of contention for LOB index Used for all external LOBs Not reported in data dictionary views
53
juliandyke.com
Application Design
juliandyke.com
54
Perform DML on sets of rows INSERT, UPDATE and DELETE sets rather than individual rows Avoid procedural code PL/SQL, PRO*C, JDBC etc Use bulk operations for DML Set array size Use PL/SQL FORALL and BULK statements Consider using analytic queries Reduce number of block visits per query
55
juliandyke.com
LOOP FETCH FROM c1 INTO lx, ly, lz; .... INSERT INTO t2 (x,y,z) VALUES (lx, ly, lz); .... END LOOP;
56
juliandyke.com
57
juliandyke.com
Avoid unnecessary DDL Statements Avoid dynamic schema changes Temporary tables are often created and dropped during report generation For example:
LOOP ... CREATE TABLE t1 (...); ... DROP TABLE t1; ... END LOOP;
58
juliandyke.com
Avoid reading recently updated blocks on other instances Use Database services to ensure node affinity Minimize transaction lengths Maximize COMMIT frequency Minimize undo generation Drop unused indexes Compress data columns e.g. use D or E instead of DISABLED or ENABLED Use nullable columns Use nullable indexes e.g. NULL / Y Avoid updating columns where data has not changed Before and after values are saved even for unchanged data
59
juliandyke.com
Minimize use of DROP and TRUNCATE Require inter-instance synchronization to invalidate block ranges in buffer caches DELETE may 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 dirty blocks in remote buffer caches are flushed back to disk Optimizer may not consider synchronization costs when selecting a parallel execution plan
60
juliandyke.com
Use array operations for SELECT statements Reduces number of network packets required to FETCH data In SQL*Plus array size defaults to 15 To set the array size to 50 use
SET ARRAYSIZE 50
In JDBC array size defaults to 10 To set the array size for a connection to 20 rows use:
((OracleConnection)conn).setDefaultRowPrefetch (20);
61
juliandyke.com
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);
62
juliandyke.com
-- 3.052 seconds
DECLARE -- 100000 row table TYPE NUMTYPE IS TABLE OF NUMBER(6) INDEX BY BINARY_INTEGER; l_c3 NUMTYPE; CURSOR c1 IS SELECT c3 FROM t1; BEGIN OPEN c1; LOOP FETCH c1 BULK COLLECT INTO l_c3; -- 0.119 seconds EXIT WHEN c1%NOTFOUND; END LOOP; CLOSE c1; END;
63
juliandyke.com
FORALL f IN 1..100000 LOOP -- FORALL Loop 4 seconds INSERT INTO t1 VALUES (l_c1 (i), l_c2 (i), l_c3(i)); END;
64
juliandyke.com
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 always find it in AWR / STATSPACK reports Not always obvious without prior knowledge AWR / STATSPACK not very good with statements using literal values
65
juliandyke.com