I have a requirement to write a java application (web based) that will connect to an Oracle 11G databases (currently is connecting 10-12 different oracle databases), read some data from it (all are select queries).
After iterating this arraylist, I am connecting each database, fire select query (same query I am firing for all databases), get record , put it in one global collection list and close connection and continuing same process over this loop.
Currently I am "Executors" to connect multiple databases.
again using ExecutorService executor = Executors.newFixedThreadPool(20);
give one surprise to me. for creting first database connection, it shows immediate log, but for subsequent database connection, it prints logs after 60 seconds, so i am not getting why this is taking 60 secs or more for all connections?
logically, it should take time for all connections as like one.
Please suggest performance improvement for this application.
Opening a database connection is an expensive operation; if possible you should connect to each database once and reuse the connection for all queries made to that database (also known as connection pooling). It's not clear if this is what you're already doing.
Another thing that seems strange is that you have made the openConnection method synchronized. I see no need for doing that, and depending on how your code is structured it may mean that only one thread can be opening a connection at a given time. Since connecting takes a long time you'd want each thread to make its connection in parallel.
Related
This question already has answers here:
Should a database connection stay open all the time or only be opened when needed?
(5 answers)
Closed 3 years ago.
I'm connecting to a small PostgreSQL database on the local LAN using Java and running some queries and I'm not sure what is best practice.
Should I close the connection after each query or keep the connection open for the next query?
you probably want to keep the connection open for as long a possible, but in practice it probably won't matter much unless you're making hundreds of little queries and reconnecting for every one
here's an overview of what's going on, assuming your network has ping times of around 1ms:
making the socket connection, a TCP handshake should take <5ms
your client with present authentication credentials, and the server will check them. this might take a while depending on how you've got things configured but by default it'll take <1ms
your client sends a query, the server will need to populate various internal data-structures and caches (this will take a few milliseconds), the server will then be able to plan and execute the query which will vary according to the query
more details here and here
if you reuse this connection then you save the cost of authentication and catalog loading. you're therefore recommended to reuse connections where possible so this work isn't performed every time. depending on your usage this may or may not actually make much difference. for example:
if you're running lots of queries that take a few milliseconds each then it'll certainly be helpful to reuse connections
if you're mostly running queries that take many seconds to execute then this cost will be negligible
I have a problem that thought I will break down to the simplest. There two applications on LAMP stack, one PHP and another Java that do the only and exactly the same thing: run a simple query:
SELECT * FROM test
PHP execution takes 30 ms in total
Java excution takes 230 ms in total
Query run on a local MySQL client takes 10-15 ms in total
Java takes ~200 ms roughly every time only to establish a connection to the db. I understand that PHP uses some kind of built in connection pooling, therefor it doesn't need to establish a new connection every time and only takes 30 ms as a result of it.
Is the same thing possible on Java? So far I failed to achieve that. I tried to use Apache Commons DBCP connection pooling, no change at all, still takes the same time to connect to the database.
UPDATE: This is a separate question where I'm trying to make connection pooling work on Java, for those who are asking for a code example: Java MySQL connetion pool is not working
You are misunderstanding the concept and purpose of connection pooling.
Connection pooling is meant to maintain a (set of) connections on a single (Java Virtual) machine (typically, an application server). The goal is to allow multiple threads on the same machine to essentially share their connection to the database server without the need to open one everytime they need to query the database.
Stand-alone applications cannot share connections as they run on different Java Virtual Machines, or perhaps even on different physical machines.
Connection pooling would help in your stand-alone application if you had several threads making concurrent access to the database.
However, you can still measure the benefit of connection pooling by wrapping your test (the code inside your try...catch) in a loop and iterating a few times. At the first iteration, the connection needs to be opened. Don't forget to release the connection (call Con.close()), then it would be reused at the next iteration.
I am working on a basic code to access a query in a database for an alert system. I understand that the database at work (Oracle based) automatically creates a pool of connections and I wanted to know if I connect, execute the query and close the connection every 5-15seconds would the performance drop dramatically and was it the correct way to do it or would I have to leave the connection open until the infinite loop is closed?
I have someone at work telling me that closing the connection would result in the database having to lookup a query each time from scratch but if I leave it open the query will be in a cache somewhere on the database.
ResultSet rs1 = MyStatement.executeQuery(QUERY_1);
while (rs1.next()){
// do something
}
rs1.close();
rs1 = MyStatement.executeQuery(QUERY_2);
while (rs1.next()){
// do something
}
rs1.close();
Oracle can't pool connections, this has to be done on the client side
You aren't closing any connections in the code example you posted
Opening a connection is a rather slow process, so use either a fixed set of connections (typically the set has size one for things like fat client applications) or a connection pool, that pools open connections for reuse. See this question for what might be viable options for connection pools: Connection pooling options with JDBC: DBCP vs C3P0 If you are running on an application server it will probably already provide a connection pooling solution. check the documentation.
closing stuff like the resultset in your code or a connection (not in your code) should be done in a finally block. Doing the closing (and the neccessary exception handling correct is actually rather difficult. Consider using something like the JdbcTemplate of Spring (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html)
If you aren't using stuff like VPN (virtual private database) Oracle will cache execution plans of statements no matter if they come from the same connection or not. Also data accessed lately is kept in memory to make queries accessing similar data fast. So the performance decrease is really coming from the latency of establishing the connection. There is some overhead on the DB side for creating connections which in theory could affect the performance of the complete database, but it is likely to be irrelevant.
Every time a client connects to the database that connection has to be authenticated. This is obviously an overhead. Furthermore the database listener can only process a limited number of connections at the same time; if the number of simultaneous connection attempts exceeds that threshold they get put into a queue. That is also an overhead.
So the general answer is, yes, opening and closing connections is an expensive operation.
It is always beneficial to be using DB Connection pools especially if you are using a Java EE app server. Also using the connection pool which is out of the box in the Java EE app server is optimal as it will be optimized and performance tested by the App server development team.
I manage my connections by JDBC connection pool (BoneCP) and I always close the connection, the preparedStatement und the ResultSet.
But, when my programm is running for several days, the mysql-server gets slower and slower (for testing, I let my programm insert an entry every second). After 2 days, there were several seconds between the entries and that is why I think that the mysql server is getting slower and can handle the incomming transaction. Am I right?
The mysql server also uses much more of RAM and does not release the resources. So does anyone know, how I could find the error causing this behaviour? Thanks in advice!
Use the MySQL Workbench to detect open connections. It also gives you a host of options to see performance of your database server.
Also [I might be mistaken about this part of your question], when you say
I use connection pooling
why do you close the connection? Isn't that the opposite of the purpose of connection pooling?
I have a java program running 24/7. It accesses mysql database every 3 seconds only from 9.am to 3.PM. In this case when should I should open and close the MySql connection?
Should I open and close every 3 sec?
Should I open at 9.am and close at 3.pm?
Should I open once when the program start and never close it. But reconnect when connection is closed automatically and exceptions is thrown?
Why don't you simply use a connection pool. If that is too tedious since the connection will be frequently used you can reuse the same one imho.
While it is true that setting up and tearing down a MySQL connection is relatively cheap (when compared to, for example, Oracle), doing it every 3 seconds is a waste of resources. I'd cache the connection and save the overhead of creating a new database connection every time.
This depends very much on the situation. Do you connect over a WAN, is the MySQL server shared with other applications or will you be the only user (or at least will your application create most of the load?) If the database is mostly yours and it is near enough, there is little benefit in setting up and tearing down the connection daily.
This is what most applications do and this is what I'd recommend you do by default.
If you do not want to leave connections open overnight, you might able to configure your connection pool to open connections on demand and close them when they have been idle for a certain period of time -- say, 15 minutes. This would give you the benefit of being able to query the database whenever you wish and not having too many idle connections.