Skip to main content

Java EE postings (reprised)

3 replies [Last post]
Joined: 2003-08-22


The goal of this forum is to cover
performance issues throughout the stack.

In this thread I'm going to reprise a couple
posts that Scott Oaks made in our previous
forum format.


Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Joined: 2003-08-22

JDBC Statement Caching
(reprised from Scott Oaks)

In many environments when we look at performance, database
performance turns out to be at least as crucial as appserver
performance per se. One of the most significant ways this
manifests itself is in JDBC statement caching.

Statement caching allows the database to reuse the SQL plan
for a particular query, which greatly improves the
performance of the database (and hence your appserver). It's
crucial that you write your Java EE application to allow
statement caching. If you're using CMP (or something else
where the containter generates the JDBC calls), you can be
assured that your appserver does the right thing. If you are
writing servlets with your own JDBC calls, it's up to you:
you must use prepared statements, and the text of the
prepared statement must be the same in order for statement
caching to work. [The value of the parameters can differ, of
course: only the SQL text must be the same.] Hence, it's a
good idea to have a static string for each of the few SQL
statements you application needs and to create prepared
statements using those strings.

However -- and this is really the crucial point -- different
Java EE application servers enable statement caching
differently. Appservers like Weblogic handle the statement
caching internally and require no special configuration to
enable statement caching. Appservers like the Sun Java
Systems Application Server rely on the underlying JDBC
driver to handle the statement caching; in that environment,
you must explicitly enable statement caching in the JDBC
driver in order to get the best performance.

JDBC drivers typically enable statement caching by setting
one or more properties within the connection pool. In the
SJSAS admin GUI, these are additional properties for the
connection pool. The specific properties are different
depending on the JDBC driver. For Oracle, set these properties:

implicitCachingEnabled true
maxStatements 100

For the Sun JDBC drivers, set this property:

maxPooledStatements 100

For MySQL 3.19 and later, the relevant properties are these:
cachePrepStmts true
prepStmtCacheSize 100
useServerPrepStmts true


Joined: 2005-08-12

To give a little bit more insight into what happens on the database side with prepared statements(enabling statement caching), I will give an example using Oracle Database.

In Oracle, every sql statement executed goes thru a phase called "parsing". It is this parsing phase, where a sql statement will be evaluated for syntax, semantics, security, optimal execution path, and allocation of memory areas.

There are 2 types of parsing (Soft and Hard parsing). If the db finds the statement in the memory, it is soft parsing. Or if it is a new statement or a cache miss, then it is hard parsing. Hard parsing is what you need to avoid.

Once a statement is parsed, Oracle keeps the representation and it's execution plan prepared, which takes up resources and execution time. Using bind variables(parameterized queries) in your application avoid hard parsing. Hence, using bind variables is very important in sql generation because the db engine can re-use the statement.

If you do not use prepared statements, then the sql generated will be different and will end up with "hard" parsing phase. Hard parse calls significantly effect the db thruput, and in turn can affect your application performance. One way to see if you have this enabled in your application server or application is to monitor number of hard parse calls on db, if you can.

So, how does using prepared statement caching help all this? Statement caching enables prepared and callable statements on each connection to be cached(remember connection pool here) and issue the "same statement every time" to the database, which in turn will help db engine to re-use the cached statement from db memory. Because of reduced object allocations, it reduces your memory footprint and cpu cycles on app tier/jvm and also db tier. Trust me, you can bring a db to it's knees by not using prepared statements.

-- Madhu Konda

Joined: 2003-08-22

NIO and Appserver Performance
(reprised from Scott Oaks)

Check out the blog by my colleague Jeanfrancois Arcand on an
implementation of HTTP that relies on Java NIO:

We presented details of this at JavaOne two weeks ago (well,
Charlie Hunt and I presented; Jeanfrancois was home awaiting
his new baby -- congratulations Jeanfrancois!). One of the
most interesting results that we provided was a comparison
of the throughput and scaling of this architecture with
various C-based architectures.

In the past, most appservers have either used traditional
I/O (which drastically limits their scaling) or have used a
C-based HTTP interface (which gives them good scalability
but eliminates their portability). Sun's 9.0 appserver
(available now through as an
open source project through Sun's CDDL) will use NIO to
achieve scalability *and* portability by relying solely on
Java code.

In our tests so far, we've out-scaled all C-based HTTP
connectors that we've been able to test.