+ All Categories
Home > Documents > Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Date post: 23-Mar-2016
Category:
Upload: tanith
View: 37 times
Download: 2 times
Share this document with a friend
Description:
Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent. Frank Houweling (AMIS, The Netherlands) ODTUG Kscope13 . Agenda. Why is performance so important ? Overview typical ADF bottlenecks What happens too slowly What happens too often What happens too soon Too little - PowerPoint PPT Presentation
54
Frank Houweling (AMIS, The Netherlands) ODTUG Kscope13 Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent 1
Transcript
Page 1: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Frank Houweling (AMIS, The Netherlands) ODTUG Kscope13

Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

1

Page 2: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Agenda

• Why is performance so important ?• Overview typical ADF bottlenecks• What happens too slowly• What happens too often• What happens too soon• Too little • Too big• Demo (examples)• AMIS ADF Performance Monitor• Summary performance tips

Page 3: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Customers do not accept slow applications anymore

Page 4: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Overview typical bottlenecks (1)

What happens too slowly:• ViewObject queries• PL-SQL calls from ApplicationModules• EntityObject DML operations• ApplicationModule passivation & activation• ApplicationModule transactionsWhat happens too often:• ViewObject queries (more than 1 of the same VO during a request)• ViewObject queries caused by unintentionally left iterator bindings in pageDefs• Database roundtrips• HTTP requests• Loading too much database rows in ADF BC memory• ApplicationModule passivation / activation• Logging that could have been turned off (or less)

Page 5: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Overview typical bottlenecks (2)

What happens too soon:• Taskflow executions• Loading (immediate versus lazy)Too little:• Caching• JVM heap spaceToo big:• Too big scope for managed beans• Too much HTML sent to browser

Page 6: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Agenda

• Why is performance so important ?• Overview typical ADF bottlenecks• What happens too slowly

Page 7: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Slow database executions

• Many bottlenecks are simply caused by slow ViewObject queries, PL-SQL calls or EntityObject DML operations

• Often hard to track which queries are slow• Some queries are only slow for certain bind parameters• Some queries are not slow during a development phase but are slow in a

production environment (that has much more data)

RDBMS

Page 8: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Measure execution time of ViewObject queries

Override executeQueryForCollection() in project base class during development

Output in JDeveloper server log:

Page 9: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Other ways to detect slow database executions (1)

• Oracle ADF Logger diagnostic tool in JDeveloper

Page 10: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Other ways to detect slow database executions (2)

• Set up a database trace-Queries from database perspective-Disadvantage: database executions not from ADF application’s perspective, often not easy to relate database trace to ADF executions

• AppDynamics (general JEE performance monitor)-Could be useful to monitor slow requests and see slow database executions-Problem: looks at the request URL to distinguish http request and business transactions. ADF uses often the same URL for many http requests

Page 11: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Agenda

• Why is performance so important ?• Overview typical ADF bottlenecks• What happens too slowly• What happens too often

Page 12: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too often executed ViewObject queries

• More than 1 execution of the same VO during a single http request (!)• (Unintentionally) programmed by developer

Often caused by:• Inefficient set refresh property of iterator binding in pageDef• ViewAccessor’s queries that are used for lookup items in af:table,

af:treeTable or af:tree components• Default implementation of a <af:treetable> or <af:tree> with associations

and viewlinks executes each detail VO node in a mini query• Custom ADFBC overrides and programmatically executed iterators• Nested <af:iterators> in <af:iterators> on iterator bindings that bind to

ViewObjects with associations and viewlinks• Master-detail-detail behavior with ADFBC with associations and viewlinks

Page 13: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

PageDef iterator binding refresh property

• Refreshing an iterator binding reconnects it with its underlying RowSetIterator object (=ViewObject)

• Default value is deferred. This means ‘on demand’: the binding will not be executed unless its value is accessed

• In most cases: leave it at default (=deferred)• Be very careful with refresh=“IfNeeded” - is the root cause of many

unnecessary queries. It means: refresh and re-execute the query when any of the bind parameter values have changed

• Use RefreshCondition if you want to refresh query conditionally• Don’t use refresh=“Always” - the underlying ViewObject will re-execute

multiple times during a http request

Page 14: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too often executed ViewObject mini-queries (1)

• Default implementation of <af:treetable> or <af:tree> with associations and viewlinks executes each detail VO node query and is a potential bottleneck

• Solution: create a custom managed bean responsible for building the hierarchical structure in Java - it retrieves the data from the BindingContainer and manages the page

• Replace the multiple queries with one single query with nodeId’s and parentNodeId’s

Page 15: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too often executed ViewObject mini-queries (2)

• Nested <af:iterators> in <af:iterators> on iterator bindings that bind to ViewObjects with associations and viewlinks cause multiple mini-queries

• Solution: create a custom managed bean responsible for building the hierarchical structure in Java en that retrieves the data from the BindingContainer and manages the page

Page 16: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too often executed ViewObject mini-queries (3)

• Custom ADFBC overrides and programmatically execute iterators can have unexpected behavior – many mini queries

• Every getter method in a ViewRowImpl can be called multiple times during a request

Page 17: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Fetching the data of the Pension fund for the web application

>< select * from employers where id = < 324>

select * from participants where employer_id = < 324>

select * from benefits where participant_id = <#>

1 record

100s records

10s records

Page 18: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Reporting on many employers

select * from employers

select * from participants where employer_id = <#>

select * from benefits where participant_id = <#>

10k records

100k records

100s records1 query

100s queries

10k queries

Page 19: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Single bulk retrieve replacing multiple queries

• Have the database bulk up the data retrieval• Return Ref Cursor, Types and Collections or JSON/XML

select * from employerswhere id in <some set> select *

from participants where employer_id in <some set>

select b.* from benefits b join participants p on (p.id = b.participant_id)where p.employer_id in <some set>

Benefits Package

Page 20: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Unintentionally left iterators in pageDefs

• ViewObject queries caused by unintentionally left iterators in pageDefs• Iterator bindings can still be refreshed and the ViewObject unnecessary

executed - for example when you have Refresh=“ifNeeded”)

Page 21: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too many database roundtrips (1)

• The ViewObject fetch mode and fetch size properties (ViewObject General Tab - Tuning section) controls how many rows will be returned in each round-trip to and from the database

Page 22: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too many database roundtrips (2)

• ViewObject fetchMode and fetchSize are underestimated properties and have big performance impact

• The default value is 1 - will give poor performance (unless only one row will be fetched)

• Set the in Batches of value to gain performance efficiencies. • Rule of thumb: If you are displaying n rows at a time in the user

interface, set the fetch size to at least n + 1, so that each page of results can be retrieved in a single round-trip to and from the database

• For selection lists where you need all the records set fetchMode to All at once

• As you increase this value, however, you also increase the client-side buffer requirements, so you shouldn't just set this number arbitrarily high

Page 23: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too many HTTP Requests (1)

• The iterator binding rangesize property represents the current set of objects to be displayed on the page

• Rule of thumb: for af:tables, af:treetable and af:tree components set the rangesize to the max number of records that you can display in the browser, not more (usually not more than 50)

• If you display 30 records and your rangesize=25 (default), than 2 http request from the client are needed to show the 30 records (!)

• For selection lists where you need all records set rangesize to -1

Page 24: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too many HTTP Requests (2)

• Make use of the powerful ADF AJAX capabilities• Set where possible on all af:command<xxx> components (buttons, links,

menu-items, etc) partialSubmit="true“ and immediate="true" (check the 18 lessons of ADF and JSF interaction of Steven Davelaar)

• If you don’t use partialSubmit="true“ than the whole page is refreshed • More http requests could be sent to the server than needed

HTTP Requests

Page 25: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Demo

• World’s most inefficient HR application !

Page 26: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too much data in ADFBC memory (1)

• Try to avoid loading more database rows than you need• Be careful if you really do need to load a proportional number of database

rows

Page 27: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too much data in ADFBC memory (2)

• Database rows are cached in the ViewRowStorage and EntityCache• If you query a proportional number of database rows

many database rows memory consumption can be high• Use accessmode=Range Paging if you have to display +- more than 250

records in an af:table, af:treeTable or af:tree • Query resource intensive data only on demand (BLOBS, CLOBS, etc.)• Limit the ViewObject query result rows by bind parameters where possible• Use read-only ViewObjects where update is not needed (if EO based:

deselect the updatable checkbox

Page 28: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Demo ViewObject Range Paging

Page 29: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too frequent ApplicationModule passivation & activation (1)

• Application module (AM) pooling enables multiple users to share several application module instances. It may involve saving and retrieving session state data from the database. This mechanism is provided to make the application scalable and becomes very important under high load with many concurrent users

Page 30: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

• Often during development the AM pooling settings are not considered important and left at their default.

• On a production environment, not setting these parameters correct (and leaving them at the default values) can be very inefficient and may cause many unneeded passivations and activations

• Carefully read the documentation in the ADF Fusion developers Guide (Ch. 44 of the 11gR2 Fusion Developer Guide)

Too frequent ApplicationModule passivation & activation (2)

Page 31: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

ApplicationModule pooling guidelines (1)

Recommended by Oracle Fusion Guide:Oracle’s rule of thumb for setting the AM pool size is to set the maxavailablesize and the recyclethreshold parameters to the expected number of peak concurrent users that perform multiple operations with short think times:

• jbo.ampool.maxavailablesize = jbo.recyclethreshold• jbo.ampool.minavailablesize = 80 % of jbo.ampool.maxavailablesize• jbo.ampool.doampooling=true (default)• jbo.doconnectionpooling=false (default)

This avoids application module instantiation time when load increases - the hit is taken at server startup. This also avoids recycling (passivation cycle) of AM under normal load.Be careful: setting the maxavailablesize and recyclethreshold too high can result in a (too) big memory consumption (Java heap space) and can cause out-of-memory-exceptions.

Page 32: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

ApplicationModule pooling guidelines (2)

Recommended by Duncan Mills:• Increase jbo.ampool.maxinactiveage• Set jbo.ampool.timetolive = -1

Results in more available AMs and avoid passivation/ activation costsMore recommended by Oracle Fusion Guide:• If your highest concern and priority is to limit the number of database

connections, set jbo.doconnectionpooling=true (in combination with jbo.txn.disconnect_level=1), otherwise leave it at false (default)

• Option for ADF applications with proportionally many root AMs, many users and many database connections for each user

Page 33: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too many database connections

• Monitor the number of database connections in the Weblogic Console

• set jbo.doconnectionpooling=true and jbo.txn.disconnect_level=1

Page 34: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too much logging on

• Switch to SEVERE at the WLS / EM level

Page 35: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Agenda

• Why is performance so important ?• Overview typical ADF bottlenecks• What happens too slowly• What happens too often• What happens too soon

Page 36: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Executed too soon (1)

• Example: af:panelTabbed component with in each af: showDetailItem an af:region that starts a taskflow execution

Page 37: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Executed too soon (2)

.jsff page: PageDefinition:

Page 38: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Executed too soon (3)

• Use childCreation="lazyUncached“ or childCreation="lazy“ to defer taskflow execution of all tabs until the tab is opened

• For popups, use childCreation="deferred”

• For tasklows in regions, use activation="conditional" and a RefreshCondition on the taskflow executable

Page 39: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Instantiated too soon

• Defer the runtime instantiation of ViewObject and nested ApplicationModule instances until the time they are used

Page 40: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Loaded too soonImmediate versus lazy

Important to consider for the following components:

• af:table, af:treeTable, af:tree• af:popup• af:menu• dvt<xxx> (graphs)

• Lazy delivery should be used for tables, or other stamped components, which are known to have a slow fetch time (when they show many records, or the query is slow)

Page 41: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Design your pages smart

• Do not display too much data on a page, keep your page design simple if possible

• Some organizations do still have old browsers (IE7) that can handle limited amounts of HTML and JavaScript

• Do not unnecessarily query data that is not immediately needed (unopened tree nodes, inactive tabs, invisible popups, unopened dropdown lists, etc.)

Page 42: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Example bad practice ADF10g app

?15%

30%

35%15%

5%

Page 43: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Agenda

• Why is performance so important ?• Overview typical ADF bottlenecks• What happens too slowly• What happens too often• What happens too soon• Too little

Page 44: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too little Caching

Page 45: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too little JVM Heap size

Recommended by Duncan Mills:• Set (–Xms–Xmx) as large as possible within available physical memory

• Generational parallel garbage collection strategy is recommended to maximize throughput: -Xgc:genpar (JRockit)

Page 46: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Agenda

• Why is performance so important ?• Overview typical ADF bottlenecks• What happens too slowly• What happens too often• What happens too soon• Too little • Too big

Page 47: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too big scope for managed beans

• Use as small memory scopes as possible

Page 48: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too much table rows to browser

• fetchsize on af:table, af:treeTable and af:tree components defines the number of rows

sent to the browser• Should be (and is default) the same as

the iterator rangesize in the pageDef• Bad practice: setting a high fetchsize

on af:table, af:treeTable or af:tree component.As a result, the browser gets a big http response and has to build up a very big DOM tree(example: 3,9 MB http response (!) )

Page 49: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too much HTML to the browser (1)

Make IDs of the following ADF faces container components as small as possible (max 2 characters):

• af:pageTemplate • af:region • af:panelCollection• af:table• af:treetable• af:tree• af:iterator

Page 50: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too much HTML to the browser (2)

• Monitor HTTP traffic in browser (for example firebug)• Look for big files

HTML

Page 51: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Too much HTML to the browser (3)

• Make the container component IDs as small as possible, for example:<af:pageTemplate id="t“ > <af:panelCollection id="c“ ><af:treeTable id=”utt” ><af:region id="r4“ >

HTML

Page 52: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Summary ADF Performance Tips

1. Smart application design - do not unnecessarily query data that is not immediately needed (unopened tree nodes, inactive tabs, invisible popups, unopened dropdown lists, etc.)

2. Query resource intensive data only on demand (BLOBS, CLOBS, etc.)3. Detect and avoid multiple unnecessary ViewObject query executions4. Detect and tune ViewObject slow queries5. Set efficient ViewObject fetchsizes6. Set efficient PageDefinition Iterator rangesizes7. Use partialSubmit=true and immediate = true where possible on:

af:commandButton, af:commandImageLink, af:commandLink, af:commandMenuItem, af:commandNavigationItem, af:commandToolbarButton.

8. If you are working with more than 500 records in tables, set the ViewObject property accessmode to ‘Range paging’

9. Make IDs of ADF faces container components (af:pageTemplate, af:region, af:panelCollection, af:table, af:treetable, af:tree) as small as possible

10. Learn about (and try out) the most efficient Application Module pooling settings for your specific situation

Page 53: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

ADF Performance Monitor

Page 54: Improve Your ADF Fusion Application's Response Time by as Much as 70 Percent

Resources

• Fusion Middleware Performance and tuning guide• AMIS technology blog• Blogs by Duncan Mills• Blogs by Andrejus Baranovskis


Recommended