Hi,

> I recently analyzed a JDBC application
>for performance problems (using JProbe) and found that 2/3 of my time was
>being spent by the driver looking up my column number with the name. 

>Always refer to columns by number, and read them all in one time -- first to
>last -- into a data structure from which you can randomly access what you
>need how you need it.

This is excellent advice; having had the same performance problems myself I can't 
agree enough.  

The primary problem with JDBC is the amount of String handling it does - in an 
application where I was storing 
and manipulating up to 80Mb of Strings in memory, and database access occurred on 
approximately every 
100th String access, the JDBC driver was responsible for more String object creation 
and use than my portion 
of the logic (which, being prototype at the time, did not bother to use StringBuffer 
or any other optimizations).

My recommendations in this regard are fairly straightforward:

1. Use PreparedStatement wherever you can!  Creating a new Statement for every 
database access often 
seems easier, but uses a LOT of resources, especially Strings.  PreparedStatement is 
also somewhat faster.  On 
the same rant, don't create new Statements every time - a Statement object can be 
reused with different 
queries.

2. Whenever you do SELECTs and the like, never use "SELECT *" - always name your 
parameters (SELECT 
alpha, beta FROM myTable).  More than just the sheer issue of design and associated 
problems if you modify 
the table, you are guaranteed to have the columns returned in the listed order, 
allowing you to safely use 
column number indexing to retrieve values, and saving that really nasty overhead of 
looking up column names 
to get numbers (which, not surprisingly, creates an astonishing amount of Strings).

3. Cache your results and close the ResultSet as soon as possible.  Remember that in 
Java assigning a String 
to another data structure does not make a new object - it assigns a reference to the 
same String object that 
JDBC created, because Strings are immutable.  Typically only one ResultSet can be used 
by a Connection at a 
time, so this is prudent to improve the efficiency of multithreaded applications.  Use 
the cached results for as 
long as possible, to prevent more JDBC calls.

4. Use SQL, not your own logic.  Too many people fall prey to the "select everything 
and then pick out what I 
want" problem.  Every SQL row you transfer from a database creates new objects.  In 
Java there is no reuse of 
these objects, so retrieving 100 rows so that you can pick out five of them wastes a 
lot of memory, and means 
the garbage collector has to do a lot of extra work later.  Use the WHERE clause, use 
SORT, use GROUP BY 
and use joins.  People also have some sort of innate need to select from one table, 
and then use that data to 
select from another table, and so on.  Maybe they need SQL tuition, or maybe they 
somehow believe their 
method is better.  It isn't ... get over it ... use joins.

5. Linked to (4), only transfer what you need.  If you only need the Username and 
Password columns, don't use 
"SELECT *" or also retrieve the user's real name and postal address, "on the off 
chance" that you may need 
them.  Either you do or you don't.  


Wells, thats my R2.
Given the exchange rate ... that's not far off 2c.
Shyte.

Twylite

Reply via email to