Reputation: 350
I'm looking back at an application which I built and released some time ago. At the time there wasn't much time for optimisation, but I've got some time to optimise it a little now.
I have a java DAL class which loads an object with items from the database as follows:
sql = "SELECT COUNT(*) FROM projects";
count = execute(sql) // this returns the count
sql = "SELECT p.*, m.name AS clientName"
...
sql = sql + " FROM projects p"
sql = sql + " LEFT JOIN clients m ON p.clientID = m.id";
Project[] p = execute(sql, count); //this returns Project array
The problem I have is the count script takes over 4 seconds to run and the select script takes about 2 seconds. Although this is delivered to the presentation layer asynchronously, 6 seconds is still a very long time to wait (there are only about 300 records in the projects table).
I'm thinking that I can probably improve this by adding stored procedures and maybe adding additional filters to the scripts such as "where active=1". But I'm wondering if anyone can suggest a better solution overall?
Thanks
EDIT: I've been doing some further testing with System.nanoTime() and I've found the largest chunk of the 4 seconds (3.8s) from the count script happens inside the execute function in one line:
Connection c = getCon();
The getCon function does this:
if (con == null) {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection(db_connect_string,db_userid,db_password);
}
...
So I have a new question now - why would it take 3.8 seconds to get the db connection?
Upvotes: 1
Views: 972
Reputation: 62583
Try using SELECT COUNT(1) FROM projects
instead of COUNT(*)
. It has been known to improve some performance.
With regards to your edit, looks like you're not making use of Connection Pooling mechanism. If you don't use one, each call will try and open up a new connection which can be expensive. A Connection Pool, on the other hand, maintains a pool of connections, ready for use whenever needed. If you do a connection.close()
in your code, it will simply go to the pool for reuse rather than completely disconnected.
You might want to check a list of commonly used connection pools. I prefer DBCP or C3P0.
Note: If you use an application server such as WebSphere / WebLogic / JBoss, you don't need to worry about this as it would've already been taken care of for you. All you've to do is to make your application use DataSource
s instead of direct DriverManager.getConnection()
and configure the connections on your application server.
Upvotes: 2
Reputation: 41858
Make certain you have indexes on your table, but before changing any code I would write some automated tests to get numbers.
Then as you make changes you can compare the actual numbers and see what will work best for you.
That way, if you try a stored procedure, you can see how that works, for example.
Upvotes: 0