Sie sind auf Seite 1von 74

Best Practices for Developing

Performant Applications
Luxi Chidambaran
Oracle
The following is intended to outline our general
product direction. It is intended for information
purposes only, and may not be incorporated into any
contract. It is not a commitment to deliver any
material, code, or functionality, and should not be
relied upon in making purchasing decisions.
The development, release, and timing of any
features or functionality described for Oracles
products remains at the sole discretion of Oracle.
Overview
Application Lifecycle
Best Practices for Database Access Performance
Performance Tools
Use Cases
Conclusion
Application Lifecycle
Requirements
Design
Code
Testing
Deployment
Production
Maintenance
WHAT ABOUT
PERFORMANCE?
Oops! What about Performance?
Performance issues found once customer deploys
Often causes reactive fire-fighting
Performance needs to be baked into the development
process
Application Lifecycle
Requirements
Design
Code
Testing
Deployment
Production
Maintenance
Performance
Requirements?
Does Design account for
key Performance
objectives?
Are Performance Best
Practices conformed to?
Performance/Scalability
Testing?
Deployment
Guidelines for best
Performance?
Performance
Monitoring?
Performance
Regressions?
Focus of this presentation
Not about SQL tuning
Not about Oracle Database instance tuning
It is about writing efficient Database access code in
your application
It is also about some of performance tools that can
help
<Insert Picture Here>
Best Practices for Database
Access Performance
Database Access Performance: Basic
Rules
Avoid repeated creation/destruction
application/database-driver interface objects.
Eliminates
Unnecessary code path
Excessive garbage collection
Minimize contention for shared objects such as:
Persistent structures in the database
Resources (e.g connections)
Follow Database API Best Practices
Top Two out of Top Ten Mistakes Found In Oracle Systems:
Bad Connection Management
Bad Use of Cursors and the Shared Pool
Recurring Design Patterns
Patterns in terms of Best Practices with respect to
using Database APIs
Enable an application developer to consistently apply
established practices
Enable a performance engineer to advise an
application developer with respect to potential
application changes
Follow Database API usage Best
Practices
Connection Pooling
Bind Variables
Statement Caching
Turn off Auto Commits
Reducing Roundtrips
Array DML
Array Fetching and Prefetching
PL/SQL and J ava stored procedures
Result Caching
Secure Files
<Insert Picture Here>
Performance Tools
AWR and ADDM
Built into the Oracle Database 10g
Automatic Workload Repository (AWR)
Evolution of statspack
Built-in repository
Captures performance statistics at regular intervals
Automatic Database Diagnostic Monitor (ADDM)
Methodically analyses captured AWR stats
Generates recommendations
Require Diagnostic Pack which requires a separate
license
Reports provide invaluable input for diagnosing
performance issues
Getting ADDM/AWR Reports
Create an AWR Snapshot
BEGIN
DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT ();
END;
Run your workload
Create a second AWR Snapshot
BEGIN
DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT ();
END;
Generate reports
@$ORACLE_HOME/rdbms/admin/addmrpt.sql
@$ORACLE_HOME/rdbms/admin/awrrpt.sql
<Insert Picture Here>
Use cases
<Insert Picture Here>
Dont create a storm
What is this AWR report stating?
More from the same AWR report
Why not just run ADDM?
Fi ndi ng 3: Sessi on Connect and Di sconnect
I mpact i s 9. 59 act i ve sessi ons, 80. 97%of t ot al act i vi t y.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sessi on connect and di sconnect cal l s wer e consumi ng si gni f i cant dat abase t i me.
Recommendat i on 1: Appl i cat i on Anal ysi s
Est i mat ed benef i t i s 9. 59 act i ve sessi ons, 80. 97%of t ot al act i vi t y.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Act i on
I nvest i gat e appl i cat i on l ogi c f or possi bl e r educt i on of connect and
di sconnect cal l s. For exampl e, you mi ght use a connect i on pool scheme i n
t he mi ddl e t i er .
Excessive Connection Activity
Database Connections expensive to create
Spawn O/S process, network connection, several roundtrips
Associated database authentication and session creation
Database Connections are expensive to tear down!
Repeatedly Connecting/Disconnecting can be a huge
scaling issue
Turn on Connection Pooling
Java Implicit Connection Cache
Mai n Thr ead:
/ / Set Dat aSour ce pr oper t i es
ods. set URL( ur l ) ;
ods. set User ( user ) ;
ods. set Passwor d( passwor d) ;
ods.setConnectionCachingEnabled(true);
ods.setConnectionCacheName(CPOOL");
Properties prop = new Properties ();
prop.setProperty("MaxLimit", ""+THREAD_COUNT);
prop.setProperty("MinLimit", "" +THREAD_COUNT);
prop.setProperty("InitialLimit", ""+THREAD_COUNT);
ods.setConnectionCacheProperties(prop);
Thr ead:
/ / Obt ai n a connect i on
connect i on = dat aSour ce. getConnection( ) ;
/ / r un t he wor kl oad
doWor k( connect i on) ;
/ / cl ose t he connect i on when done
connect i on. close( ) ;
OCI Session Pool
Mai n Thr ead:
/* create a homogeneous session pool */
OCISessionPoolCreate( envhp, er r hp,
spool hp, / * sessi on pool handl e */
( Or aText **) pool Name, pool NameLenp,
( const Or aText *) connst r , st r l en( connst r ) ,
min, max, increment,/* pool size constraints */
( Or aText *) " hr " , st r l en( ( char *) " hr " ) ,
( Or aText *) apppasswor d,
st r l en( ( char *) apppasswor d) ,
OCI_SPC_HOMOGENEOUS) ;
Thr ead:
OCISessionGet( envhp, er r hp,
&svchp, / * r et ur ned dat abase connect i on */
aut hp, / * i ni t i al i zed aut hent i cat i on handl e */
/ * connect pool name */
( Or aText *) pool Name, pool NameLen,
/ * sessi on t aggi ng par amet er s: opt i onal */
NULL, 0, NULL, NULL, NULL,
OCI _SESSGET_SPOOL) ;
do_wor kl oad( svchp, er r hp, pt r ) ;
OCISessionRelease( svchp, er r hp, NULL, 0, OCI _DEFAULT) ;
Database Resident Connection Pool
(DRCP) in Oracle Database 11g
Fallback when there is no application tier connection
pooling
Also useful for sharing connections across middle tier
hosts
Supported only for OCI and PHP applications
Scales to tens of thousands of database connections
even on a commodity box
Enable with dbms_connection_pool.start_pool
Connect String
Easy Connect: //localhost:1521/oowlab:POOLED
TNS Connect String: (SERVER=POOLED)
<Insert Picture Here>
Parsing is hard
What is the related AWR report
stating?
More from the same AWR report
Lets run ADDM
Fi ndi ng 2: Har d Par se Due t o Li t er al Usage
I mpact i s 8. 32 act i ve sessi ons, 79. 74%of t ot al act i vi t y.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SQL st at ement s wer e not shar ed due t o t he usage of l i t er al s. Thi s r esul t ed i n
addi t i onal har d par ses whi ch wer e consumi ng si gni f i cant dat abase t i me.
Recommendat i on 1: Appl i cat i on Anal ysi s
Est i mat ed benef i t i s 8. 32 act i ve sessi ons, 79. 74%of t ot al act i vi t y.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Act i on
I nvest i gat e appl i cat i on l ogi c f or possi bl e use of bi nd var i abl es i nst ead
of l i t er al s.
Act i on
Al t er nat i vel y, you may set t he par amet er " cur sor _shar i ng" t o " f or ce" .
Rat i onal e
At l east 39 SQL st at ement s wi t h FORCE_MATCHI NG_SI GNATURE
5551823750033335619 and PLAN_HASH_VALUE 1833546154 wer e f ound t o be
usi ng l i t er al s. Look i n V$SQL f or exampl es of such SQL st at ement s.
Lack of Bind Variables
Hard Parse is expensive
Creates shared cursor in SGA
Causes library cache latch contention
Causes shared pool contention
Causes scalability issues
Use Bind Variables
Reduces hard parses on the server
Reduces risk of SQL Injection: potential security issue
Bind Variables in Java
Instead of:
St r i ng quer y = " SELECT EMPLOYEE_I D, LAST_NAME, SALARY FROM "
+" EMPLOYEES WHERE EMPLOYEE_I D = "
+ generateNumber(MIN_EMPLOYEE_ID, MAX_EMPLOYEE_ID);
pst mt = connect i on. pr epar eSt at ement ( quer y) ;
r s = pst mt . execut eQuer y( ) ;
Change to:
St r i ng quer y = " SELECT EMPLOYEE_I D, LAST_NAME, SALARY FROM "
+" EMPLOYEES WHERE EMPLOYEE_I D = ?";
pst mt = connect i on. pr epar eSt at ement ( quer y) ;
pstmt.setInt(1, n);
r s = pst mt . execut eQuer y( ) ;
Bind Variables in OCI
static char *MY_SELECT = "select employee_id, last_name, salary from \
employees where employee_id = :EMPNO";
OCIBind *bndp1;
OCI St mt *st mt hp;
ub4 emp_id;
OCI St mt Pr epar e2 ( svchp, &st mt hp, / * r et ur ned st mt handl e */
er r hp, / * er r or handl e */
( const Or aText *) MY_SELECT,
st r l en( ( char *) MY_SELECT) ,
NULL, 0, / * t aggi ng par amet er s: opt i onal */
OCI _NTV_SYNTAX, OCI _DEFAULT) ;
/* bind input parameters */
OCIBindByName( st mt hp, &bndp1, er r hp, ( t ext *) ":EMPNO",
- 1, &(emp_id), sizeof(emp_id), SQLT_INT,
NULL, NULL, NULL, 0, NULL, OCI _DEFAULT) ;
Literal Replacement
Fallback if application cannot be changed to use
binds
init.ora parameter
CURSOR_SHARING={FORCE|SIMILAR|EXACT}
Default is EXACT
<Insert Picture Here>
Soft things can hurt
What is this AWR report stating?
Lets run ADDM
Fi ndi ng 3: Sof t Par se
I mpact i s 1. 1 act i ve sessi ons, 10. 59%of t ot al act i vi t y.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sof t par si ng of SQL st at ement s was consumi ng si gni f i cant dat abase t i me.
Recommendat i on 1: Appl i cat i on Anal ysi s
Est i mat ed benef i t i s 1. 1 act i ve sessi ons, 10. 59%of t ot al act i vi t y.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Act i on
I nvest i gat e appl i cat i on l ogi c t o keep open t he f r equent l y used cur sor s.
Not e t hat cur sor s ar e cl osed by bot h cur sor cl ose cal l s and sessi on
di sconnect s.
Excessive Soft Parsing:
Lack of Statement Caching
Soft Parsing
Session executes a statement that exists in shared pool
Creates session specific cursor context
Repeats metadata processing
Use Statement Caching
Keeps frequently used session cursors open
Reduces soft parses on the Server
Not only faster but more scalable
Cuts repeated metadata processing
Consumes less network bandwidth
Cuts code path in driver/application tier
Statement Caching in Java
/ / Obt ai n a connect i on
connect i on = dat aSour ce. get Connect i on( ) ;
/ / Enabl e st at ement cachi ng
((OracleConnection)connection).setStatementCacheSize(20);
((OracleConnection)connection).setImplicitCachingEnabled(true);
Statement Caching in OCI
Initialize the OCI Session Pool with statement cache
ub4 stmt_cachesize = 20;
/* set the statement cache size for all sessions in the pool */
OCIAttrSet(spoolhp, OCI_HTYPE_SPOOL, &stmt_cachesize, 0,
OCI_ATTR_SPOOL_STMTCACHESIZE, errhp);
/ * cr eat e a homogeneous sessi on pool */
OCISessionPoolCreate( envhp, er r hp,
spoolhp, / * sessi on pool handl e */
. . . ,
OCI _SPC_HOMOGENEOUS|
OCI_SPC_STMTCACHE) ; / * modes */
Use new flavors of prepare/release calls
OCIStmtPrepare2(), OCIStmtRelease()
Session Cached Cursors in the
Database
Fallback if you cannot change the application to use
statement caching
session_cached_cursors = X
Defaults have changed in various releases
Oracle Database 11g Default = 50
<Insert Picture Here>
Wrong Default
What is this AWR report stating?
AWR Reports indicate excessive
transaction activity
Lets run ADDM
Fi ndi ng 2: Commi t s and Rol l backs
I mpact i s 15. 69 act i ve sessi ons, 90. 54%of t ot al act i vi t y.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Wai t s on event " l og f i l e sync" whi l e per f or mi ng COMMI T and ROLLBACK oper at i ons
wer e consumi ng si gni f i cant dat abase t i me.
Recommendat i on 1: Appl i cat i on Anal ysi s
Est i mat ed benef i t i s 15. 69 act i ve sessi ons, 90. 54%of t ot al act i vi t y.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Act i on
I nvest i gat e appl i cat i on l ogi c f or possi bl e r educt i on i n t he number of
COMMI T oper at i ons by i ncr easi ng t he si ze of t r ansact i ons.
Rat i onal e
The appl i cat i on was per f or mi ng 345218 t r ansact i ons per mi nut e wi t h an
aver age r edo si ze of 483 byt es per t r ansact i on.
Auto Commits
Beware. Many database drivers (e.g. J DBC) have
auto commit on
Causes more transactions, log flushes
Increases response time
Breaks atomicity of the transactions
Use driver specific knob to turn off auto commits
e.g. J DBC
conn.setAutoCommit(false);
<Insert Picture Here>
Bulk up and speed up
Array DML/Fetching/Prefetching
Use array operations instead of single row operations
Single row DMLs/fetches incur excessive roundtrips
Check array size is large enough
Some drivers support prefetching instead of array
fetching
Identify tuning candidates via Enterprise Manager or
V$SQL or AWR sql statistics tables.
Array Fetch size from Enterprise
Manager
Array Fetch size from V$SQL example
SQL> select sql_text, executions, fetches, rows_processed from V$SQL where sql_text like 'select
city from locations';
SQL_TEXT EXECUTIONS FETCHES ROWS_PROCESSED
------------------------------ ---------- ---------- --------------
select city from locations 8800 26400 202400
Looking at V$SQL
ROWS_PROCESSED/EXECUTION = 23
Bump up client side prefetch or array-fetch to 24
Fetches all rows in one roundtrip (instead of three)
V$SQL information can get aged out
Same statistics available via persistent AWR tables
DBA_HIST_SQLSTAT, DBA_HIST_SQLTEXT
Array Fetching in Java
St r i ng quer y = " SELECT EMPLOYEE_I D, LAST_NAME FROM EMPLOYEES "
+" WHERE EMPLOYEE_I D > ? "
+" ORDER BY EMPLOYEE_I D" ;
pst mt = connect i on. pr epar eSt at ement ( quer y) ;
pst mt . set I nt ( 1, gener at eNumber ( MI N_EMPLOYEE_I D, MAX_EMPLOYEE_I D) ) ;
pstmt.setFetchSize(20);
rs = pstmt.executeQuery();
Resul t Set Met aDat a r smd = r s. get Met aDat a( ) ;
i nt col umnCount = r smd. get Col umnCount ( ) ;
while (rs.next()) {
f or ( i nt i = 1; i <= col umnCount ; ++i )
Syst em. out . pr i nt l n( r smd. get Col umnName( i ) +" [ "
+r smd. get Col umnTypeName( i ) +" ] : "
+r s. get St r i ng( i ) ) ;
}
Array Fetching in OCI
#define ARRAY_SIZE 20 /* Fetch 20 row at a time */
/ * Ensur e t hat OCI Def i ne cal l s ar e done wi t h bi g enough buf f er s */
whi l e ( ! done)
{
st at us = OCIStmtFetch( st mt hp, er r hp, ARRAY_SIZE,
OCI_FETCH_NEXT, OCI _DEFAULT) ;
i f ( ( st at us == OCI _SUCCESS) | | ( st at us == OCI _NO_DATA) )
{
i f ( st at us == OCI _SUCCESS)
r ows = ARRAY_SI ZE; / * al l r ows asked f or wer e obt ai ned */
el se i f ( st at us == OCI _NO_DATA)
{
/ * mi ght have got t en f ewer r ows */
OCI At t r Get ( st mt hp, OCI _HTYPE_STMT, &r ows, ( ub4 *) NULL,
OCI _ATTR_ROWS_FETCHED, er r hp) ;
done = TRUE;
}
}
el se
/ * handl e er r or */
Array DML in Java
St r i ng dml = " UPDATE EMPLOYEES SET SALARY = ?"
+" WHERE EMPLOYEE_I D = ?" ;
pst mt = connect i on. pr epar eSt at ement ( dml ) ;
((OraclePreparedStatement)pstmt).setExecuteBatch(UPDATE_COUNT);
f or ( i nt i = 0; i < UPDATE_COUNT; ++i )
{
pst mt . set I nt ( 1, gener at eNumber ( MI N_SALARY, MAX_SALARY) ) ;
pst mt . set I nt ( 2, gener at eNumber ( mi n, max) ) ;
pst mt . execut eUpdat e( ) ;
compl et edOp++;
}
Array DML in OCI
st at i c char *MY_DML = ( char *) " updat e empl oyees set sal ar y = : sal \
wher e empl oyee_i d = :id" ;
OCI Bi nd *bndp1, *bndp2;
OCI St mt *st mt hp;
OCI St mt Pr epar e2 ( svchp, &st mt hp, . . . ) ; / * r et ur ned st mt handl e */
/ * do par amet er bi ndi ngs */
OCIBindByPos( st mt hp, &bndp1, er r hp, 1,
(void *) array_on_client,
(sword) sizeof(array_element),
SQLT_I NT, NULL, NULL,
NULL, 0, NULL, OCI _DEFAULT) ;
/ * bi nd ot her par amet er s */
/ * execut e t he st at ement and commi t */
OCIStmtExecute( svchp, st mt hp, er r hp, update_num, 0,
( OCI Snapshot *) NULL, ( OCI Snapshot *) NULL,
OCI _COMMI T_ON_SUCCESS) ;
<Insert Picture Here>
Dont be chatty
Stored Procedures
Bundle multiple SQL statements in one call
Use anonymous blocks or stored procedures
Eliminates roundtrips to database
Eliminates moving data between database and client
Can improve performance dramatically
Monitor roundtrips and bytes transferred stats
High values may indicate optimization opportunities
Network Stats in AWR
<Insert Picture Here>
Cash in with Result Caching
Benefits
Easy to Use Cache
Add /*+ result_cache */ hint in SQL
Frees application developers from building custom caches
Extends server-side result caching to client side memory
Leverages cheaper client-side memory
Each application has its working set cached locally
Achieves better performance by eliminating server
roundtrips
Improves server scalability by saving server resources
Transparently maintains cache consistency with server
side changes
Identifying Candidate Queries for
Client Result Caching from AWR
Identifying Candidate Queries for
Client Result Caching from AWR
Identifying Candidate Queries for
Client Result Caching from AWR
Identify top SELECT statements
BY CPU
BY Elapsed Time
Pick queries
On tables that are not updated often
With result sets can fit in available client memory
Ideal candidates for /*+ result_cache */ hint
init.ora parameter
CLIENT_RESULT_CACHE_SIZE
Niles Benchmark Performance
Improvements
0%
100%
200%
300%
400%
500%
600%
Improvement
DB CPU Reduction:
Up to
600%
0%
20%
40%
60%
80%
100%
120%
140%
Improvement
Response Time :
Up to
15-22% Faster
<Insert Picture Here>
Dealing with large objects?
Secure Files Best Practices
Data API
LOBs are handled like LONG or LONG RAW columns
Recommended for small LOBs
No extra roundtrips
LOB API
Recommended for offset based access
Use for large LOBs (MBs)
Extra roundtrips (pre 11g) to get data, length, chunk-size
Oracle Database 11g Improvements for LOBs
OCI does Zero Copy network transfer
15-20% improvement in CPU usage for LOBs over 100k
LOB Prefetch eliminates some extra roundtrips
Set SDU_SIZE for Large Data Transfers
Controls SQL*Net packet size
Default is 8k starting with Oracle Database 11g
Set it upto 32k (max supported) if application does
Large Result set array fetches
Large Array DML operations
Large PL/SQL IN/OUT bind transfers
LOBs
Needs to be set on both client and server
Monitor network stats in AWR
<Insert Picture Here>
Performance Monitoring
Monitoring Performance by specific
criteria
AWR and ADDM provide instance level statistics
An instance might be running several application
modules
Need ability to diagnose performance issues for a
specific application or module
End-to-end monitoring attributes
Specifies an application action within a MODULE ACTION
Specifies a functional area of an application MODULE
Specifies an application (configured at deployment) SERVICE
Specifies the "real" end user CLIENT_IDENTIFIER
Description Property
Coding End-to-end monitoring
attributes
Instrument code for setting the end-to-end attributes
Enables Database to track statistics based on these
attributes
Lookup your driver documentation for more details
Settings piggybacked on Database calls in J DBC and OCI
In iAS environments: DMS (Dynamic Monitoring Service)
overrides J DBC user supplied values, if configured
Benefits of End-to-end Monitoring
Turn stats on/off dynamically based on end-to-end attributes
DBMS_MONITOR
DBMS_MONITOR.CLIENT_ID_STAT_ENABLE('john.doe');
DBMS_MONITOR.SERV_MOD_ACT_STAT_ENABLE( 'APPS1','PAYROLL');
Statistics available in
V$CLIENT_STATS
V$SERVICE_STATS
V$SERV_MOD_ACT_STATS
V$ACTIVE_SESSION_HISTORY
Helps answer real questions in production:
Why is application user john.doe experiencing poor response times?
Why is a particular application slow?
Why is a particular application module slow?
Why is a particular application action slow?
Summary
Overview of Performance in the Application Lifecycle
Recurring patterns in diverse stacks
Performance tools: AWR and ADDM
Use cases
How the tools help identify potential issues early in the
development cycle
Best Practices for Database API usage
End-to-end Performance Monitoring
White Paper
Building High Performance Drivers for Oracle
Database 11g: OCI Tips and Techniques
www.oracle.com/technology/tech/oci/pdf/building-best-drivers.v9.pdf
Related Sessions
Session ID: S298816
Session Title: Hands-on Lab: Best Practices for Developing Performant
Applications with Oracle Database 11g
Track: Oracle Develop: Database
Venue: Marriott
Room: Golden Gate B1
Date: 2008-09-22
Start Time: 16:00
Session ID: S298768
Session Title: Best Practices for Deployment, Performance, and Diagnosability of
Oracle Net Services
Track: Database
Room: Rm104
Date: 2008-09-25
Start Time: 10:30
The preceding is intended to outline our general
product direction. It is intended for information
purposes only, and may not be incorporated into any
contract. It is not a commitment to deliver any
material, code, or functionality, and should not be
relied upon in making purchasing decisions.
The development, release, and timing of any
features or functionality described for Oracles
products remains at the sole discretion of Oracle.

Das könnte Ihnen auch gefallen