问题
In my application I use Spring MVC with DAO pattern to access MSSql database with JdbcTemplate. Everything is working fine but I have noticed that first query takes a bit longer then next queries in each single request.
I wrote a simple test:
String sql = "SELECT 1";
for (int i = 0; i < 5; i++) {
long startTime = System.currentTimeMillis();
jdbcTemplate.queryForList(sql);
logger.debug("query took: " + TimeHelper.showDuration(startTime));
}
the result is:
2012-08-28 12:55:07,665 | Start
2012-08-28 12:55:08,878 | query took: 424 milliseconds
2012-08-28 12:55:08,893 | query took: 15 milliseconds
2012-08-28 12:55:08,908 | query took: 14 milliseconds
2012-08-28 12:55:08,922 | query took: 14 milliseconds
2012-08-28 12:55:08,937 | query took: 14 milliseconds
I understand that there are some activities that Spring is doing to get all beans ready. But if there is request to server that executes only 1 query then it takes 424 miliseconds on each request.
My question is: Is this behavior OK? Or there can be some bug in my code? Does it work so that on each request Spring needs this time for initialization? (and all other queries in request will run fast then)? Or I can do some startup initialization and then during each request the first query will take 15 ms too?
My configuration is folowing:
datasource: class="org.apache.commons.dbcp.BasicDataSource"
dao is injected to test class with:
@Resource(name="testDao")
private TestDao testDao;
I use annotations based approach. Test class and DAO doesn't use @Transaction.
EDIT: I also tried to configure initialSize but this didn't help, (with initialSize=2 it takes 800ms, with initialSize=1 it takes 400ms - each request).
I don't understand why it takes 400ms on each request when it is possible to have it for 15 ms. It seems like some overhead with Spring. :(
回答1:
Your DataSource is a connection pool. The first query needs to connect. Subsequent queries reuse the connection. You could either configure dbcp to pre-create a few connections or connect and release manually right after the app starts.
回答2:
Have a look at the javadoc and source. getExceptionTranslator()
probably involves some work to set up. Maybe you can control when that work happens with the lazy-init
parameter.
回答3:
I checked that connection pool and its connections (initialSize) are created during first call when connection is needed, and then later it is reused in all requests, this is how it should work :), I have also noticed that 400ms time is lower (about 100ms) when there are multiple requests at the same time. I think the reason for initial longer time is because of establishing a TCP connection as John Watts mentioned or because of some Spring background management.
来源:https://stackoverflow.com/questions/12158309/spring-dao-first-query-with-jdbctemplate-takes-much-longer-time